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

use*_*385 11 rdf semantic-web path sparql

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

SELECT ?p
WHERE { :startNode ?p* :endNode }
Run Code Online (Sandbox Code Playgroud)

where ?p*指定路径.有办法做到这一点吗?

Jos*_*lor 18

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

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

您可以通过使用通配符和它的否定来使用通配符,因此您可以执行一个简单的查询来检查是否存在连接两个资源的路径:

<source> (<>|!<>)* <target>
Run Code Online (Sandbox Code Playgroud)

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

<source> (:|!:)* <target>
Run Code Online (Sandbox Code Playgroud)

如果两个节点之间存在路径(或多个路径),则可以使用连接的通配符路径将其拆分?p,然后查找?p路径上的所有s:

<source> (:|!:)* ?x .
?x ?p ?y .
?y (:|!:)* <target> .
Run Code Online (Sandbox Code Playgroud)

我认为,你可以使用空白节点而不是?x?y:

<source> (:|!:)* [ ?p [ (:|!:)* <target> ] ]
Run Code Online (Sandbox Code Playgroud)

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

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

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

@prefix : <urn:ex:> .

:a :p1 :b .
:b :p2 :c .
:c :p3 :d .
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用这样的查询来获取路径及其位置中的每个属性.(这只有在有一条路径的情况下才有效.请参阅我的答案是否可以在SPARQL中的RDF集合中获取元素的位置?有关其工作原理的更多信息.)

prefix : <urn:ex:>

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

现在,如果您通过命令对这些结果进行排序?pos并将查询包装在另一个中,那么您可以使用group_concaton ?p来按顺序获取单个属性字符串.(保留的顺序不能得到保证,但这是非常常见的行为.请参阅我的答案以获取矩阵获取该技术如何工作的另一个示例,以及我对SPARQL 1.1中GROUP_CONCAT中的Ordering的回答,以讨论它为什么不保证.)

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
}
Run Code Online (Sandbox Code Playgroud)
-----------------------------------------
| path                                  |
=========================================
| "<urn:ex:p1> <urn:ex:p2> <urn:ex:p3>" |
-----------------------------------------
Run Code Online (Sandbox Code Playgroud)