2016-08-15 50 views
1

我需要使用一個SPARQL查詢檢索與特定謂詞標識的主題關聯的所有「屬性」。我特別避免使用術語「導出三元組」,因爲我不一定需要CONSTRUCT(可以是CONSTRUCTSELCET可以)。使用SPARQL檢索具有子節點的RDF資源

某些「屬性」本身就是節點(可能是空白節點),需要「遞歸」檢索。謂詞的集合是已知的(我有一個全面的列表,他們都在相同的前綴,他們都是那些前綴)。 「遞歸」的謂詞是它們的一個子集。

@prefix ex: <http://example.org/ex/> . 
@prefix : <http://example.org/> . 
ex:toExport 
    a ex:SomeClass ;   # to retrieve, as in rdf: namespace 
    :pred-1 "Some value" ;  # to retrieve "as is" 
    :pred-2 42 ;    # to retrieve "as is" 
    :pred-3 [     # blank-node to be retrieved as a whole 
     :pred-1 "..." ; 
     :pred-2 1024 
    ] ; 
    :pred-4 [ 
     :pred-3 [    # "sub" blank-node to be retrieved as a whole 
      :pred-1 "..." ; 
      :pred-2 1024 
     ] 
    ] ; 
    :pred-5 [     # same for a "sub-list" 
     :pred-6 (ex:something ex:else) 
    ] ; 
    :pred-7 ex:subOne .   # "sub-property" can be a non-blank node... 

ex:subOne      # ...defined as a resource of its own 
    :pred-1 "Value" ; 
    :pred-2 0 . 

在上面的例子,我需要與謂詞:pred-1:pred-2(簡單的值),:pred-3(它的值是在這些實施例2點的三元組一個空節點),:pred-4檢索三元組(一空白節點本身以及一個額外的空白節點)等等。:pred-7很有趣,因爲它顯示所有「子節點」不一定是空白節點。

下面的查詢是我找到符合我的要求最接近的,但它使用虹膜,這是我想避免的查詢對大型數據集的字符串值正則表達式:

CONSTRUCT { 
    ?s ?p ?o . 
    ?o ?pp ?oo . 
    ?oo ?ppp ?ooo . 
} 
WHERE { 
{ 
    ?s ?p ?o . 
    FILTER (regex(str(?p), "^(http://www.w3.org/ns/shacl#|http://www.w3.org/1999/02/22-rdf-syntax-ns#)")) 
    OPTIONAL 
    { 
     ?o ?pp ?oo . 
     FILTER (regex(str(?pp), "^(http://www.w3.org/ns/shacl#|http://www.w3.org/1999/02/22-rdf-syntax-ns#)")) 
     OPTIONAL 
     { 
      ?oo ?ppp ?ooo . 
      FILTER (regex(str(?ppp), "^(http://www.w3.org/ns/shacl#|http://www.w3.org/1999/02/22-rdf-syntax-ns#)")) 
     } 
    } 
} 

的謂詞集合就像20個不同的謂詞,因此可以很容易地將它們列出來,但如果它是以組合方式進行排列的話,它是可以管理的。

+0

我沒有看到很多優化它的潛力,但您至少可以在單獨的子SELECT查詢中首先查詢不同的屬性,以便它只執行一次。查詢的其餘部分與預期一樣,生成深度爲3的子圖 – AKSW

回答

0

專門爲正則表達式:如果你的目標是簡單地使它更易於閱讀,你可以沿着這些路線做一些事情:

FILTER(STRSTARTS(STR(?p), STR(rdf:)) || STRSTARTS(STR(?p), STR(shacl:))) 

這樣可以節省您不必使用長的正則表達式與完整的命名空間虹膜,並且將邏輯或移出正則表達式並將其移入SPARQL過濾器邏輯本身(這可能更有效)。

除此之外,我還沒有立即看到在單個SPARQL查詢中改進此功能的簡單方法。但是,如果您願意妥協並對結果進行一些後處理,則可以使用更簡單的查詢獲得相當接近的結果。

通常情況下,這種事情也提供使用簡單DESCRIBE查詢相當不錯:

DESCRIBE ex:toExport 

然而,有一個在你的情況下兩個要求,使這更困難:

  1. :pred-7的值也應該返回:DESCRIBE通常只返回所描述的資源的空白節點閉包,所以這不會是一個完整的答案。
  2. 只應返回某些屬性:DESCRIBE通常返回全部屬性。

對於第一個問題,我們可以擴展DESCRIBE查詢以接近您的預期結果。例如,我們可以修改它不僅描述ex:toExport而且是通過所需性能的一個連接到ex:toExport的IRI所有資源?x

DESCRIBE ex:toExport ?x 
WHERE { 
     ex:toExport ?p ?x . 
     FILTER(isIRI(?x)) 
     FILTER(STRSTARTS(STR(?p), STR(rdf:)) || STRSTARTS(STR(?p), STR(shacl:))) 
} 

這個結果會檢索所有你想要的數據,但它仍然沒有按解決問題2:它不會將返回的屬性限制爲您所期望的屬性,但將返回全部屬性ex:toExport?x

過濾這些不需要的屬性當然可以在後期處理中完成,但是否適合您的方案取決於首先在數據中的「不需要」屬性的數量。

最後一條警告:DESCRIBE查詢的確切結果是依賴於實現的。 大多數實現返回某種形式的空節點閉包,但有變化。檢查你的SPARQL引擎的文檔(或者給它一個測試旋轉看看它是什麼)。