【问题标题】:OpenLink Virtuoso: Finding if two nodes are connected within a certain distanceOpenLink Virtuoso:查找两个节点是否在一定距离内连接
【发布时间】:2010-10-12 12:14:35
【问题描述】:

如何使用 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:knows 更改为 ?p 似乎有点过头了。

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

【问题讨论】:

  • 如果您有理由相信只有一条路径连接节点,那么您可以使用 SPARQL 1.1 实现这一点。这是一个可行的假设吗?

标签: sparql virtuoso


【解决方案1】:

您应该能够在查询中使用?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

【讨论】:

  • @Joshua Taylor 我正在尝试将它应用到 f​​reebase 上。我想找到实体`basekb:m.01000w`和basekb:m.010dg5之间的距离。这是正确的吗? FILTER (?s= basekb:m.01000w &amp;&amp; ?o =basekb:m.010dg5 )
  • @HaniGoc 这是一个老问题,我没有写这个答案,我几乎没有你问我的上下文。
【解决方案2】:

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

@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: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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-13
    • 1970-01-01
    • 2011-04-02
    • 1970-01-01
    • 2021-08-07
    • 2015-11-19
    • 1970-01-01
    相关资源
    最近更新 更多