2014-03-28 32 views
1

我想创建一个SPARQL查询来查找Jim知道的所有人,然后找到Jim知道哪些人知道,然后像链一样的东西。Sparql,如何合并不同的结果

比如我有一个:

Jim knows Clare and Antoine  
Clare knows Jim and David 
Antoine knows David and Clare 
David knows Clare 

所以结果则:

result1: Clare, Antoine 
result2: Jim, David, David, Clare 
result3: Clare, David, Clare, Clare, Jim, David 

或多或少我已经像一棵树。

我想要的是将result1,result2result3合并为result4。所以result4将是:

result4: clare, antoine, jim, david, david, clare, clare, david, clare, clare, jim, david. 

,然后用DISTINCT以便移除重复的。我该如何做到这一点?

SELECT ?Result1 ?Result2 ?Result3 
WHERE{ 
    { 
     base:Knows dc:Names  _:BN1 . 
     _:BN1  dc:FName  "Jim"; 
       dc:KnownFName   ?Result1 . 
    } 
    . 
    { 
     base:Knows dc:Names  _:BN2 . 
     _:BN2  dc:FName  ?Result1; 
       dc:KnownFName   ?Result2 . 
    } 
    . 
    { 
     base:Knows dc:Names  _:BN3 . 
     _:BN3  dc:FName  ?Result2; 
       dc:KnownFName   ?Result3 . 
    } 
} 

回答

4

比方说,你的例子表示如下:

<http://example.com/person/1> <http://xmlns.com/foaf/0.1/knows> <http://example.com/person/2> . 
<http://example.com/person/1> <http://xmlns.com/foaf/0.1/knows> <http://example.com/person/3> . 
<http://example.com/person/2> <http://xmlns.com/foaf/0.1/knows> <http://example.com/person/1> . 
<http://example.com/person/2> <http://xmlns.com/foaf/0.1/knows> <http://example.com/person/4> . 
<http://example.com/person/3> <http://xmlns.com/foaf/0.1/knows> <http://example.com/person/4> . 
<http://example.com/person/3> <http://xmlns.com/foaf/0.1/knows> <http://example.com/person/2> . 
<http://example.com/person/4> <http://xmlns.com/foaf/0.1/knows> <http://example.com/person/2> . 

<http://example.com/person/1> <http://www.w3.org/2000/01/rdf-schema#label> "Jim" . 
<http://example.com/person/2> <http://www.w3.org/2000/01/rdf-schema#label> "Clare" . 
<http://example.com/person/3> <http://www.w3.org/2000/01/rdf-schema#label> "Antoine" . 
<http://example.com/person/4> <http://www.w3.org/2000/01/rdf-schema#label> "David" . 

然后你可以使用SPARQL联盟功能通过合并三个单独的查询结果,以达到你想要的东西。它可以更简洁地表示使用SPARQL属性路径:

PREFIX foaf: <http://xmlns.com/foaf/0.1/> 

SELECT DISTINCT * WHERE { 
{ SELECT * WHERE { 
<http://example.com/person/1> foaf:knows/rdfs:label ?knowsName . 
} } 
UNION 
{ SELECT * WHERE { 
<http://example.com/person/1> foaf:knows/foaf:knows/rdfs:label ?knowsName . 
} } 
UNION 
{ SELECT * WHERE { 
<http://example.com/person/1> foaf:knows/foaf:knows/foaf:knows/rdfs:label ?knowsName . 
} } 
} 

您还可以通过一个单一的属性路径表达式得到knows谓词的充分传递闭包:

PREFIX foaf: <http://xmlns.com/foaf/0.1/> 

SELECT * WHERE { 
<http://example.com/person/1> foaf:knows+/rdfs:label ?knowsName . 
} 

...如果你triplestore支持SPARQL 1.1。否则,你将不得不使用推理或重复查询来完全关闭。

+1

一千喜欢....我或多或少的结构和作品像一个魅力。 TYVM! – user3358377