2010-10-12 71 views
2

如何使用Virtuoso查找图形中两个节点之间的距离?我读过及物单证,但他们限制你到一个谓语例如为:OpenLink Virtuoso:查找是否在一定距离内连接了两个节点

SELECT ?link ?g ?step ?path 
WHERE 
{ 
    { 
    SELECT ?s ?o ?g 
    WHERE 
     { 
     graph ?g {?s foaf:knows ?o } 
     } 
    } OPTION (TRANSITIVE, t_distinct, t_in(?s), t_out(?o), t_no_cycles, T_shortest_only, 
    t_step (?s) as ?link, t_step ('path_id') as ?path, t_step ('step_no') as ?step, t_direction 3) . 
    FILTER (?s= <http://www.w3.org/People/Berners-Lee/card#i> 
    && ?o = <http://www.advogato.org/person/mparaz/foaf.rdf#me>) 
} 
LIMIT 20 

只有穿越foaf:knows而不是任何谓词类型。我怎样才能把这个扩展到“任何谓词”?我不需要实际的路径,只需要一个真/假(ASK查询)。改变foaf:知道?p似乎是一种矫枉过正。

我目前正在执行一组递归ASK以查明两个节点是否在特定距离内连接,但看起来效率不高。

+0

如果您有理由相信,有只有一个连接节点的路径,那么你可以用SPARQL 1.1来移植它。这是一个可行的假设吗? – 2014-03-06 17:13:12

回答

4

您应该能够在查询中使用?p而不是foaf:knows来确定节点之间是否存在路径。例如:

SELECT ?link ?g ?step ?path 
    WHERE 
    { 
    { 
     SELECT ?s ?o ?g 
     WHERE 
     { 
      graph ?g {?s ?p ?o } 
     } 
    } OPTION (TRANSITIVE, t_distinct, t_in(?s), t_out(?o), t_no_cycles, T_shortest_only, 
    t_step (?s) as ?link, t_step ('path_id') as ?path, t_step ('step_no') as ?step, t_direction 3) . 
    FILTER (?s= <http://www.w3.org/People/Berners-Lee/card#i> 
    && ?o = <http://www.advogato.org/person/mparaz/foaf.rdf#me>) 
    } 
    LIMIT 20 
+0

@Joshua Taylor我正在尝试将它应用于freebase。我想找到实体'basekb:m.01000w'和'basekb:m.010dg5'之间的距离。这是对的吗? 'FILTER(?s = basekb:m.01000w &&?o = basekb:m.010dg5)' – 2016-02-16 13:04:27

+0

@HaniGoc这是一个老问题,我没有写这个答案,而且我几乎没有关于你的内容'再问我。 – 2016-02-16 13:08:33

1

这里有一个工作,如果有,你有兴趣 如果你有这样的数据(注意,是连接资源的不同性质)的节点之间最多只有一个路径的方法:

@prefix : <https://stackoverflow.com/q/3914522/1281433/> 

:a :p :b . 
:b :q :c . 
:c :r :d . 

然后,像下面这样的查询找到每对节点之间的距离。物业路径(:|!:)包含::(即任何物品)以外的物业。因此(:|!:)*是零或更多的任何财产的事件;这是一个通配符路径。 (这里使用的技术在Is it possible to get the position of an element in an RDF Collection in SPARQL?更全面的描述。)

prefix : <https://stackoverflow.com/q/3914522/1281433/> 

select ?begin ?end (count(?mid)-1 as ?distance) where { 
?begin (:|!:)* ?mid . 
?mid (:|!:)* ?end . 
} 
group by ?begin ?end 
order by ?begin ?end ?distance 
-------------------------- 
| begin | end | distance | 
========================== 
| :a | :a | 0  | 
| :a | :b | 1  | 
| :a | :c | 2  | 
| :a | :d | 3  | 
| :b | :b | 0  | 
| :b | :c | 1  | 
| :b | :d | 2  | 
| :c | :c | 0  | 
| :c | :d | 1  | 
| :d | :d | 0  | 
-------------------------- 

如果仅想了解是否有两个节点之间的路径是小于一些特定的长度,你可以使用一个ask查询,而不是select,修复?begin?end的值,并限制值count(?mid)-1,而不是将其绑定到?distance。例如,是否有从:a:d长度小于三的路径?

prefix : <https://stackoverflow.com/q/3914522/1281433/> 

ask { 
values (?begin ?end) { (:a :d) } 
?begin (:|!:)* ?mid . 
?mid (:|!:)* ?end . 
} 
group by ?begin ?end 
having ((count(?mid)-1 < 3)) 
Ask => No 

在另一方面,有来自:a小于5的路径:c,长度:

prefix : <https://stackoverflow.com/q/3914522/1281433/> 

ask { 
values (?begin ?end) { (:a :c) } 
?begin (:|!:)* ?mid . 
?mid (:|!:)* ?end . 
} 
group by ?begin ?end 
having ((count(?mid)-1 < 5)) 
Ask => Yes 
相关问题