2014-09-25 35 views
3

我做遞歸第一個查詢來搜索特定號碼的所有子:SPARQL - 遞歸的回報深度

SELECT distinct ?child 
WHERE { 
?child rdfs:subClassOf* num_108999. 
} 

我想補充遞歸的深度,例如,如果我的數據看起來像這樣的:

108999 --> 2004 --> 218 

我想要的回報:

?child | ?depth 
_______|_______ 
2004 | 1 
218 | 2 

爲了讓我可以使用 「聯盟」 和ELT {N}:

SELECT * WHERE { 
{ 
    SELECT distinct (1 as ?count) ?child 
    WHERE { 
    ?child rdfs:subClassOf{1} num_108999. 
    } 
}UNION{ 
    SELECT distinct (2 as ?count) ?child 
    WHERE { 
    ?child rdfs:subClassOf{2} num_108999. 
    } 
} 

我認爲這沒關係與2的深度,但在完整的數據,我有20深... 我如何通過自動增加可變深度的數量?

謝謝!

更新: 我發現了一個小解決方案:將elce {+}和elt {*}拆分爲{oc}。

SELECT distinct (count(?mid) as ?count) ?child 
WHERE { 
?mid rdfs:subClassOf+ num_108999. 
?child rdfs:subClassOf* ?mid. 
} 

它適用於二叉樹。但我沒有二叉樹,我的數據是這樣的:

  /--> 2003 --\ 
108999 --/    \--> 218 
     \---> 2004 --/ 

前面的查詢統計每個路徑:108999到2003年,2003年218,108999到2004年和2004年以218

所以返回值是4,而不是2 ...

回答

0

首先,請注意

?child rdfs:subClassOf{1} num_108999. 

是不合法的SPARQL。 SPARQL 1.1沒有包含屬性路徑的{m,n}說明符,儘管它在早期的草案中。但是,Virtuoso確實支持它。它的規範實際上讓你做

{n} # exactly n 
{m,} # at least m 
{,n} # no more than n 
{m,n} # at least m and no more than n 

這最後的形式是你想要什麼(如果你使用一個支持它的端點):

?child rdfs:subClassOf{1,2} num_108999 

這並不能幫助你儘管找到了特定路徑的長度,但您無法在SPARQL中完成此操作。如果從開始到結束只有一條路徑,那麼你可以,但如果有多條路徑,則不能。

+0

謝謝你的回答。爲了建立聯盟,形式{m,n}很棒。但我想返回結果中的m或n ... – Matthieu 2014-09-29 14:48:47

+0

@Matthieu是的,正如我在我的回答中所說的,「[它]不能幫助您找到特定路徑的長度,但您可以如果從開始到結束只有一條路徑,那麼你可以,但如果有多條路徑,你不能。「 SPARQL不提供區分同一節點之間不同路徑的方法。中間計數技術通過計算從一開始就可以達到多少個節點並且從哪個末端可達到。不幸的是,這隻有在單一路徑時纔有效。 – 2014-09-29 14:50:53