具有任意属性的SPARQL属性路径查询

时间:2014-11-02 11:15:17

标签: path rdf sparql semantic-web

任意长度的

SPARQL property path查询需要使用特定属性。我想查询并查找从资源开始到另一个资源结束的任何路径。例如:

SELECT ?p
WHERE { :startNode ?p* :endNode }

其中?p*指定路径。有没有办法做到这一点?

1 个答案:

答案 0 :(得分:18)

你是对的,你不能在属性路径表达式中使用变量。但是,可以做的一些事情可能会对您有所帮助。

用于检查 路径是否存在的通配符

您可以通过取消通配符及其否定来使用通配符,这样您就可以执行一个简单的查询来检查是否存在连接两个资源的路径:

<source> (<>|!<>)* <target>

如果您定义了:前缀,则可以更短,因为:是有效的IRI:

<source> (:|!:)* <target>

如果两个节点之间存在路径(或多个路径),则可以使用?p加入的通配符路径将其拆分,从而找到路径上的所有?p

<source> (:|!:)* ?x .
?x ?p ?y .
?y (:|!:)* <target> .

我认为,通过使用空白节点代替?x?y,您可以做得更短:

<source> (:|!:)* [ ?p [ (:|!:)* <target> ] ]

可能不起作用。我似乎记得在空白节点中某些地方实际上不允许使用属性路径的语法。我不确定。)

对于单个路径,获取属性和位置,然后group_concat

现在,如果两个资源之间只有一条路径,您甚至可以获取该路径中的属性及其位置。您可以按这些位置排序,然后使用group by将属性连接成一个字符串。这可能是最容易看到的一个例子。假设您已获得以下数据,其中包含从:a:d的单一路径:

@prefix : <urn:ex:> .

:a :p1 :b .
:b :p2 :c .
:c :p3 :d .

然后,您可以使用这样的查询来获取路径及其位置中的每个属性。 (这只适用于有单一路径的情况。请参阅我对Is it possible to get the position of an element in an RDF Collection in SPARQL?的回答,了解其工作原理。)

prefix : <urn:ex:>

select ?p (count(?mid) as ?pos) where {
  :a (:|!:)* ?mid .
  ?mid (:|!:)* ?x .
  ?x ?p ?y. 
  ?y (:|!:)* :d
}
group by ?x ?p ?y
-------------
| p   | pos |
=============
| :p2 | 2   |
| :p1 | 1   |
| :p3 | 3   |
-------------

现在,如果您按?pos订购这些结果并将查询查询包装在另一个结果中,那么您可以使用group_concat上的?p获取单个字符串属性的顺序。 (保留的顺序不是保证,但它是非常常见的行为。请参阅我对obtain the matrix in protege的回答,了解该技术如何工作的另一个示例,并my answer to Ordering in GROUP_CONCAT in SPARQL 1.1讨论为什么它不能保证。)

prefix : <urn:ex:>

select (group_concat(concat('<',str(?p),'>');separator=' ') as ?path) {
  select ?p (count(?mid) as ?pos) where {
    :a (:|!:)* ?mid .
    ?mid (:|!:)* ?x .
    ?x ?p ?y. 
    ?y (:|!:)* :d
  }
  group by ?x ?p ?y
  order by ?pos
}
-----------------------------------------
| path                                  |
=========================================
| "<urn:ex:p1> <urn:ex:p2> <urn:ex:p3>" |
-----------------------------------------