如何使用Virtuoso找到图形中2个节点之间的距离?我读过Transitivity文档,但它们限制你使用一个谓词,例如:
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 :(得分:4)
您应该能够在查询中使用?p
而不是foaf:knows
来确定节点之间是否存在路径。 E.g:
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
答案 1 :(得分: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
和{的值{1}},并限制?end
的值,而不是将其绑定到count(?mid)-1
。例如,是否有从?distance
到:a
长度小于3的路径?
: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 ) )