SPARQL - 获取到当前节点的最大距离为 2 的节点

SPARQL - get nodes with maximum distance 2 to current node

给定 RDF 数据库中的特定节点 http://my.org/nodes#n1,我想获取链接到 n1 的所有节点(通过各种谓词),然后再次 - 如果可能的话 - 获取连接到这些节点的所有节点。

例如,给出以下关于人物及其朋友的图表:

@prefix p: <http://helloworld.org/person#> .
@prefix r: <http://helloworld.org/relation#> .
@prefix l: <http://helloworld.org/location#> .

l:l1 l:city "Sydney" .
l:l2 l:city "Paris" .
l:l3 l:city "New York" .

p:p1 
    p:name "Jack" ;
    p:age 30 ;
    p:livingIn l:l1 .
p:p2 
    p:name "Peter" ;
    p:age 31 ;
    p:livingIn l:l1 .
p:p3 
    p:name "Carol" ;
    p:age 32 ;
    p:livingIn l:l1 .
p:p4 
    p:name "Anna" ;
    p:age 33 ;
    p:livingIn l:l2 .
p:p5 
    p:name "Chris" ;
    p:age 34 ;
    p:livingIn l:l3 .

p:p1 
    r:isFriendOf p:p2 ;
    r:isFriendOf p:p3 .

p:p3 r:isFriendOf p:p4 .

p:p4 r:isFriendOf p:p5 .

我知道节点之间只有一种关系(isFriendOf),因此很容易查询Jack的朋友和他们的朋友

PREFIX p: <http://helloworld.org/person#>
PREFIX r: <http://helloworld.org/relation#>

SELECT ?name ?friend ?foaf
WHERE {
    ?p r:isFriendOf ?o .    
    ?p p:name ?name .
    ?o p:name ?friend .
    OPTIONAL { 
        ?o r:isFriendOf ?fo .
        ?fo p:name ?foaf
    }
    FILTER ( ?p = p:p1 )
}
姓名 朋友 泡芙
“杰克” “彼得”
“杰克” “卡罗尔” “安娜”

但是,对于具有许多关系的更复杂的图形,我很难得到结果。我从

开始
PREFIX id: <http://my.org/graph#>

SELECT ?s ?p ?o ?oo
WHERE { 
    ?s ?p ?o . 
    OPTIONAL { ?o ?p ?oo . } # if an object has connections, get those as well
    FILTER( ?s = id:12345 )  # id:12345 is the node we focus on
}

但是 { ?o ?p ?oo } 部分没有给我任何东西..

您所过滤的节点 (id:12345) 在您发布的图表中不存在。

您使用的查询有两个问题:1) 您将感兴趣的资源 (id:12345) 和对象 (o) 之间的 属性 限制为相同在 ?o 和 ?oo 之间,2) 查询效率低下,因为您正在检索完整的图形,然后按感兴趣的节点进行过滤。相反,您可以这样做:

PREFIX id: <http://my.org/graph#>

SELECT ?s ?p ?o ?p1 ?oo
WHERE { 
    id:12345 ?p ?o . 
    OPTIONAL { ?o ?p1 ?oo . } 
}

如果您想要示例,请在 https://dbpedia.org/sparql

中尝试以下操作
select ?p ?o ?p1 ?oo where{
<http://dbpedia.org/resource/Madrid> ?p ?o
optional {?o ?p1 ?oo}
}

第一个结果是这样的:

p   o   p1  oo
http://www.w3.org/1999/02/22-rdf-syntax-ns#type     http://dbpedia.org/ontology/Place   http://www.w3.org/1999/02/22-rdf-syntax-ns#type     http://www.w3.org/2002/07/owl#Class

有道理:马德里是一个地方,而地方是class。

请注意,这仅获取到感兴趣节点的传出链接,而不是传入链接。为此,您必须执行以下操作:

select ?s1 ?p1 ?s ?p where{
     ?s ?p <http://dbpedia.org/resource/Madrid>
     optional {?s1 ?p1 ?s}
    }