2017-05-26 62 views
1

我有我的數據組織在多個圖表中。三聯保存的圖形很重要。數據結構是複雜的,但它可以簡化如下:SPARQL查詢在Fuseki中有效,但不在Jena中TDB

我的存儲包含蛋糕,那裏有不同的蛋糕類型的層次結構中,<cake>

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

所有子類根據他們得到如何通過創建用戶在一個用戶界面中,他們最終在一個不同的圖表。例如,如果用戶「烘烤」一塊蛋糕,則它會在<http://example.com/homemade>圖表中顯示,如果他們「購買」一個,則會進入<http://example.com/shopbought>圖表。

當我從商店取回蛋糕時,我想知道每個蛋糕是自制還是購物。沒有這方面的財產,我想檢索信息純粹基於三重圖存儲在圖表。

我已經嘗試了各種方式實現這一目標,但沒有一個在耶拿TDB工作。問題在於所有的蛋糕都是以「購物」的形式迴歸。所有的查詢都在Fuseki工作(在確切的sae數據集上),我想知道這是否是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的預期行爲