OpenLink Virtuoso:查找两个节点是否在一定距离内连接
如何使用 Virtuoso 找到图中 2 个节点之间的距离?我已阅读传递性文档,但它们将您限制为一个谓词,例如:
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:knows 更改为 ?p 似乎有点矫枉过正。
我目前正在执行一组递归 ASK,以查明两个节点是否在特定距离内连接,但这似乎效率不高。
How can I find the distance between 2 nodes in a graph using Virtuoso? I've read the Transitivity documentations but they limit you to one predicate e.g.:
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
Only traverses foaf:knows
and not any predicate type. How can I extend this to 'whatever predicate'? I don't need the actual path, just a true/false (ASK query). Changing the foaf:knows to ?p seems like an overkill.
I'm currently performing a set of recursive ASKs to find out if two nodes are connected within a specific distance but that doesn't seem efficient.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
发布评论
评论(2)
如果您感兴趣的节点之间最多只有一条路径,则这是一种可行的方法。
如果您有这样的数据(请注意,有不同的属性连接资源):
@prefix : <https://stackoverflow.com/q/3914522/1281433/>
:a :p :b .
:b :q :c .
:c :r :d .
然后像下面这样的查询会查找每对节点之间的距离。属性路径(:|!:)
包含一个属性,该属性可以是:
或:
之外的其他属性(即任何内容)。因此 (:|!:)*
是任何属性出现零次或多次;这是一个通配符路径。 (此处使用的技术在 Is it possible to get theposition 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
,修复 的值code>?begin
和 ?end
,并限制 count(?mid)-1
的值,而不是将其绑定到 ?distance.例如,是否存在从
:a
到 :d
的长度小于 3 的路径?
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
到 :c
的路径,长度小于 5:
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
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
您应该能够在查询中使用
?p
而不是foaf:knows
来确定节点之间是否存在路径。例如:You should be able to use
?p
instead offoaf:knows
in your query to determine if there's a path between the nodes. E.g.: