SPARQL:两个节点之间是否有任何路径?

时间:2015-06-18 12:59:02

标签: sparql

如果两个给定节点连接在单个/多个SPARQL端点上,是否有一种很好的SPARQL查询让我回答?

我想说我想检查两个节点是否

<http://wiktionary.dbpedia.org/resource/dog>

<http://dbpedia.org/resource/Dog>

已连接。如果是的话,我对这条路感兴趣。

猜测我已经知道它们是通过标签连接的,所以像这样的查询会返回一个长度为3的路径:

SELECT * WHERE {
  <http://wiktionary.dbpedia.org/resource/dog> ?p1 ?n1. 
  # SERVICE <http://dbpedia.org/sparql> {
    <http://dbpedia.org/resource/Dog> ?p2 ?n1 .
  # }
}

try yourself

现在如果我还没有想法并希望自动执行此操作,那该怎么办呢?任意长度和方向?

我了解SPARQL 1.1的属性路径,但它们似乎只适用于已知属性(http://www.w3.org/TR/sparql11-query/#propertypaths):

  

变量不能用作路径本身的一部分,只能用作结尾。

此外,我还想允许任何路径,因此路径上的谓词可能会发生变化。

我当前(因为我觉得很荒谬)的方法是查询长度为k的所有可能路径,最高限度为n

倾销不是我的选择,因为它有数十亿的三元组......我想使用SPARQL!

1 个答案:

答案 0 :(得分:10)

虽然您不能在属性路径中使用变量,但您可以使用通配符,因为对于任何URI,每个属性都是该属性或不是。例如,(<>|!<>)匹配任何属性,因为每个属性都是<>或不是。您可以通过在另一个方向上将其与自身交替来制作任意方向的通配符:(<>|!<>)|^(<>|!<>)。这意味着在两个节点之间存在一个路径,其中属性在任一方向上进行?u和?v

?u ((<>|!<>)|^(<>|!<>))* ?v

例如,以下查询应返回 true (表示存在路径):

ASK {
  <http://wiktionary.dbpedia.org/resource/dog> ((<>|!<>)|^(<>|!<>))* <http://dbpedia.org/resource/Dog> 
}

现在,要实际获取两个节点之间的路径链接,您可以这样做(让<wildcard>代表讨厌的外观通配符):

?start <wildcard>* ?u .
?u ?p ?v .
?v <wildcard>* ?end .

然后?u,?p和?v给你路径上的所有边缘。请注意,如果有多个路径,您将获得所有路径的所有边。由于您的通配符朝向任一方向,您实际上可以从“开始”或“结束”到达任何可以访问的内容,因此您应该考虑以某种方式限制通配符。

在您链接到的端点上,它没有,但这似乎是Virtuoso的属性路径实现的问题,而不是实际查询的问题。

请注意,如果您发生任何类型的推断,这在很多情况下都会非常满意。例如,如果你正在使用OWL,那么每个人都是猫头鹰的一个实例:Thing,所以总会有一个形式的路径:

?u→ rdf:type owl:东西← rdf:type ?v