6

Jena での SPARQL クエリの実行に苦労しています。その結果、理解できない動作が発生します...

Esco オントロジー ( https://ec.europa.eu/esco/download )にクエリを実行しようとしており、TDB を使用してオントロジーを読み込んでモデルを作成しています (用語が正確でない場合は申し訳ありませんが、私はあまり経験がありません)。

私の目標は、以前に抽出したテキストと一致するオントロジー内の役職 uri を見つけることです: 例: 抽出された用語: " acuponcteur " -> オントロジーのラベル: "Acuponcteur"@fr -> uri: < http:// ec.europa.eu/esco/occupation/14918 >

私が「奇妙な振る舞い」と呼んでいるものは、クエリを実行するときに得られる (または得られない) 結果に関連しています。

次のクエリを実行する場合:

PREFIX skos: <http://www.w3.org/2004/02/skos/core#> 
PREFIX esco: <http://ec.europa.eu/esco/model#>      
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>   
SELECT ?position    
WHERE {     
    ?s rdf:type esco:Occupation. 
    { ?position skos:prefLabel ?label. } 
    UNION 
    { ?position skos:altLabel ?label. } 
    FILTER (lcase(?label)= \"acuponcteur\"@fr ) 
}
LIMIT 10 

1分後に結果が得られます:

-----------------------------------------------
| position                                    |
===============================================
| <http://ec.europa.eu/esco/occupation/14918> |
| <http://ec.europa.eu/esco/occupation/14918> |
| <http://ec.europa.eu/esco/occupation/14918> |
| <http://ec.europa.eu/esco/occupation/14918> |
| <http://ec.europa.eu/esco/occupation/14918> |
| <http://ec.europa.eu/esco/occupation/14918> |
| <http://ec.europa.eu/esco/occupation/14918> |
| <http://ec.europa.eu/esco/occupation/14918> |
| <http://ec.europa.eu/esco/occupation/14918> |
| <http://ec.europa.eu/esco/occupation/14918> |
-----------------------------------------------

ただし、 DISTINCT キーワードを追加しようとすると、次のようになります。

PREFIX skos: <http://www.w3.org/2004/02/skos/core#> 
PREFIX esco: <http://ec.europa.eu/esco/model#>      
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>   
SELECT DISTINCT ?position   
WHERE {     
    ?s rdf:type esco:Occupation. 
    { ?position skos:prefLabel ?label. } 
    UNION 
    { ?position skos:altLabel ?label. } 
    FILTER (lcase(?label)= \"acuponcteur\"@fr ) 
}
LIMIT 10 

クエリが永遠に実行され続けるようです (20 分待ってから実行を停止しました...)

最初のクエリと同じクエリを実行すると (したがって DISTINCT なしで)、一致する別のラベル (オントロジーにないと確信しているラベル) を使用すると、同じ動作が得られます。空の結果を期待している間、それは(そのように見える)実行を続け、しばらくするとそれを強制終了する必要があります(もう一度、最大で20分待ちました):

PREFIX skos: <http://www.w3.org/2004/02/skos/core#> 
PREFIX esco: <http://ec.europa.eu/esco/model#>      
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>   
SELECT ?position    
WHERE {     
    ?s rdf:type esco:Occupation. 
    { ?position skos:prefLabel ?label. } 
    UNION 
    { ?position skos:altLabel ?label. } 
    FILTER (lcase(?label)= \"assistante scolaire\"@fr ) 
}
LIMIT 10 

私が実行しているコードに問題があるのでしょうか? そこにそれがある:

public static void main(String[] args) {

    // Make a TDB-backed dataset
    String directory = "data/testtdb" ;
    Dataset dataset = TDBFactory.createDataset(directory) ;

    // transaction (protects a TDB dataset against data corruption, unexpected process termination and system crashes)
    dataset.begin( ReadWrite.WRITE );
    // assume we want the default model, or we could get a named model here
    Model model = dataset.getDefaultModel();

    try {

          // read the input file - only needs to be done once
          String source = "data/esco.rdf";
          FileManager.get().readModel(model, source, "RDF/XML-ABBREV");

          // run a query

          String queryString =
                    "PREFIX skos: <http://www.w3.org/2004/02/skos/core#> " +
                    "PREFIX esco: <http://ec.europa.eu/esco/model#> " +     
                    "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> " +  
                    "SELECT ?position " +   
                    "WHERE { "  +   
                    "   ?s rdf:type esco:Occupation. " +
                    "   { ?position skos:prefLabel ?label. } " +
                    "   UNION " +
                    "   { ?position skos:altLabel ?label. }" +
                    "   FILTER (lcase(?label)= \"acuponcteur\"@fr ) " +
                    "}" +
                    "LIMIT 1 "  ;

          Query query = QueryFactory.create(queryString) ;

          // execute the query
          QueryExecution qexec = QueryExecutionFactory.create(query, model) ;
          try {
              ResultSet results = qexec.execSelect() ;
              // taken from apache Jena tutorial 
              ResultSetFormatter.out(System.out, results, query) ;

          } finally { 
              qexec.close() ; 
          }

      } finally {
          model.close() ;
          dataset.end();
      }

}

ここで何が間違っていますか?何か案が?

ありがとう!

4

1 に答える 1

6

大きな違いがある場合とそうでない場合がある最初のポイントとして、プロパティ パスを使用して単純化できます。

{ ?position skos:prefLabel ?label. } 
UNION 
{ ?position skos:altLabel ?label. } 

なので

?position skos:prefLabel|skos:altLabel ?label 

これにより、クエリが作成されます。

SELECT ?position    
WHERE {     
    ?s rdf:type esco:Occupation.                   # (1)
    ?position skos:prefLabel|skos:altLabel ?label  # (2)
    FILTER (lcase(?label)="acuponcteur"@fr ) 
}

このクエリの ?s のポイントは何ですか? (2) に一致するn 個の?position/?label ペアと、(1) に一致する?s のいくつかのm 個の値があります。クエリから得られる結果の数はm×nですが、?s の値を使用することはありません。DISTINCT を使用して繰り返し値を削除したようですが、最初に繰り返し値を取得する理由を確認していませんでした。無駄な行 (1) を単純に削除し、次のクエリを実行する必要があります。

SELECT DISTINCT ?position    
WHERE {     
    ?position skos:prefLabel|skos:altLabel ?label
    FILTER (lcase(?label)="acuponcteur"@fr ) 
}

その時点で、DISTINCT が不要になったとしても驚かないでしょう。

于 2014-08-14T12:48:06.623 に答える