2017-05-26 6 views
1

私は自分のデータを複数のグラフで構成しています。トリプルが保存されているグラフは重要です。データ構造は複雑ですが、次のように簡略化することができます。SPARQLクエリはFusekiでは動作しますが、Jenaでは動作しませんTDB

マイストアが異なるケーキの種類の階層がありますケーキ、それらはaで作成されます方法に応じて<cake>

<http://example.com/a1> a <http://example.com/applecake> 
<http://example.com/a2> a <http://example.com/rainbowcake> 
... 

のすべてのサブクラスが含まれていますUI内のユーザーは、別のグラフになります。たとえば、ユーザーがケーキを「焼く」場合、<http://example.com/homemade>グラフに入り、「購入」すると<http://example.com/shopbought>グラフに入ります。

私は店からケーキを回収するとき、ケーキごとに自家製か買い物かを知りたいと思います。このプロパティはありません。トリプルが格納されているグラフに基づいて純粋に情報を取得したいのですが。

これを達成する方法はさまざまですが、どれもJena TDBでは機能しません。問題は、すべてのケーキが "買い物をした"ものとして戻ってくることです。しかし、すべてのクエリはFuseki(厳密なデータセットで)で動作し、これがTDBのバグか、別の方法があるのか​​どうか疑問に思っていました。ここで(バリエーションなし)単純化されたクエリは、次のとおりです。

バージョン1:

SELECT DISTINCT * 
FROM <http://example.com/homemade> 
FROM <http://example.com/shopbought> 
FROM NAMED <http://example.com/homemade> 
FROM NAMED <http://example.com/shopbought> 
WHERE { 
    ?cake rdf:type ?caketype . 
    ?caketype rdfs:subClassOf* <cake> 
     { 
      GRAPH <http://example.com/homemade> { ?cake rdf:type ?typeHomemade } 
     } UNION { 
      GRAPH <http://example.com/shopbought> { ?cake rdf:type ?typeShopbought } 
     } 
    BIND(str(if(bound(?typeHomemade), true, false)) AS ?homemade) 
} 

バージョン2:

SELECT DISTINCT * 
    FROM <http://example.com/homemade> 
    FROM <http://example.com/shopbought> 
    FROM NAMED <http://example.com/homemade> 
    FROM NAMED <http://example.com/shopbought> 
    WHERE { 
     ?cake rdf:type ?caketype . 
     ?caketype rdfs:subClassOf* <cake> 
     GRAPH ?g { 
      ?cake rdf:type ?caketype . 
     } 
     BIND(STR(IF(?g=<http://example.com/homemade>, true, false)) AS ?homemade) 
    } 

これは布石ではなくTDBで働く理由を任意のアイデア?

編集: 私はそれがGRAPHキーワードと関係があると考え始めています。ここではいくつかの非常に簡単クエリ(布石とtdbqueryでの作業)と私はイエナのAPIを使用して取得した結果、次のとおりです。

SELECT * WHERE { GRAPH <http://example.com/homemade> { ?s ?p ?o }} 

0結果

SELECT * WHERE { GRAPH ?g { ?s ?p ?o }} 

0結果

SELECT * FROM <http://example.com/homemade> WHERE { ?s ?p ?o } 

X結果

SELECT * FROM <http://example.com/homemade> WHERE { GRAPH <http://example.com/homemade> { ?s ?p ?o }} 

の0結果

SELECT * FROM NAMED <http://example.com/homemade> WHERE { GRAPH <http://example.com/homemade> { ?s ?p ?o }} 

0結果

+1

[1](https://stackoverflow.com/questions/18891690)、[2](https://jena.apache.org/documentation/)を参照してください。 tdb/dynamic_datasets.html)、[3](https://jena.apache.org/documentation/tdb/datasets.html#special-graph-names)を参照してください。 –

+0

スタニスラフは正しいです。グラフ名には完全なURIを使用します。それ以外の場合は、ファイルのデフォルトの場所などに解決される可能性があります。 – AKSW

+0

完全なURIを使用しています。この例では短縮し、角かっこを使用して完全なURIであることを示しています。私はそれをより明確にするために私の例を更新しました。 – casualcoder

答えて

2

OK私の解決策は、私は、クエリを実行する方法で行うことを実際に持っているので。私の最初のアイデアは、クエリが関連するグラフ上でのみ実行されるようにデータセットを事前にフィルタリングすることでした(データセットには多くのグラフが含まれています。これは、SPARQLに追加するか、Jenaに直接追加することで実行できます(ただし、これは他のトリプルストアでは機能しません)。しかし、両方の方法を組み合わせることは、 "安全な側になる"ことはできません。

このクエリは、データセット全体で実行され、期待どおりに動作:

同じクエリが唯一のそれは与えないものであるグラフ問題ではありません特定のグラフ上で実行することができ
Query query = QueryFactory.create("SELECT * WHERE { GRAPH ?g { ?s ?p ?o } }", Syntax.syntaxARQ); 
QueryExecution qexec = QueryExecutionFactory.create(query, dataset); 
ResultSet result = qexec.execSelect(); 

すべての結果:

//run only on one graph 
Model target = dataset.getNamedModel("http://example.com/homemade"); 
//OR run on the union of all graphs 
Model target = dataset.getNamedModel("urn:x-arq:UnionGraph"); 
//OR run on a union of specific graphs 
Model target = ModelFactory.createUnion(dataset.getNamedModel("http://example.com/shopbought"), dataset.getNamedModel("http://example.com/homemade"), ...); 
[...] 
QueryExecution qexec = QueryExecutionFactory.create(query, target); 
[...] 

私の回避策は今、常に(SPARQL GRAPHキーワードの罰金をサポートしています)、データセット全体を照会し、各クエリのために、常にそれがデータセット全体を照会することを避けるために実行すべきでグラフを指定することでした。 これがJena APIの予想される動作であるかどうかわからない

関連する問題