任意长度的
SPARQL property path查询需要使用特定属性.我想查询并查找从资源开始并以另一资源结尾的任何路径.例如:
SELECT ?p WHERE { :startNode ?p* :endNode }
其中?p *指定路径.有没有办法这样做?
解决方法
你是对的,你不能在属性路径表达式中使用变量.有一些事情你可以做,但是,这可能会帮助你.
用于检查路径是否存在的通配符
您可以通过使用通配符来取消它的取消和否定,因此您可以执行一个简单的查询来检查是否有连接两个资源的路径:
<source> (<>|!<>)* <target>
如果你有一个定义的前缀,可以更短,因为:是一个有效的IRI:
<source> (:|!:)* <target>
如果两个节点之间有路径(或多个路径),则可以使用由pp连接的通配符路径将其拆分,因此可以找到路径上的所有?ps:
<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命令这些结果并将该查询包装在另一个中,那么可以在?p上使用group_concat来顺序获取属性的单个字符串. (保存的顺序不能保证,但这是很常见的行为.有关此技术的工作原理,请参阅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>" | -----------------------------------------