Sparql OpenLink Virtuoso:查找两个节点是否在一定距离内连接

Sparql OpenLink Virtuoso:查找两个节点是否在一定距离内连接,sparql,virtuoso,Sparql,Virtuoso,如何使用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_s

如何使用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
选择链接g步进路径
哪里
{
{
选择s?o?g
哪里
{
图g{s foaf:knows?o}
}
}选项(可传递、t_独立、t_输入(?s)、t_输出(?o)、t_无圈、t_仅最短、,
t_步骤(?s)作为链接,t_步骤('path_id')作为路径,t_步骤('step_no')作为步骤,t_方向3)。
过滤器(?s=
&&?o=)
}
限制20
仅遍历
foaf:knows
,而不遍历任何谓词类型。如何将其扩展到“任意谓词”?我不需要实际路径,只需要一个真/假(询问查询)。更改foaf:knows to?p似乎有点过头了


我目前正在执行一组递归询问,以确定两个节点是否在特定距离内连接,但这似乎没有效率。

您应该能够在查询中使用
?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
选择链接g步进路径
哪里
{
{
选择s?o?g
哪里
{
图g{s?p?o}
}
}选项(可传递、t_独立、t_输入(?s)、t_输出(?o)、t_无圈、t_仅最短、,
t_步骤(?s)作为链接,t_步骤('path_id')作为路径,t_步骤('step_no')作为步骤,t_方向3)。
过滤器(?s=
&&?o=)
}
限制20

如果您感兴趣的节点之间最多有一条路径,那么这里有一种方法是有效的。 如果您有这样的数据(请注意,连接资源的属性不同):

为了确定两个节点之间是否存在小于某个特定长度的路径,您可以使用
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 ) )
另一方面,有一条从
: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 ) )

如果您有理由相信只有一条路径连接节点,那么您可以使用SPARQL 1.1以可移植的方式实现这一点。这是一个可行的假设吗?@Joshua Taylor我正试图在freebase上应用它。我想找到实体'basekb:m.01000w'和
basekb:m.010dg5
之间的距离。对吗<代码>过滤器(?s=basekb:m.01000w&&?o=basekb:m.010dg5)@HaniGoc这是一个老问题,我没有写这个答案,我几乎没有你问我的背景。
--------------------------
| 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        |
--------------------------
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
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