具有任意属性的SPARQL属性路径查询 [英] SPARQL property path queries with arbitrary properties

查看:161
本文介绍了具有任意属性的SPARQL属性路径查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

SPARQL property path queries of arbitrary length require using specific properties. I want to query and find any path starting from a resource and ending in another resource. For example:

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

其中?p*指定路径.有办法吗?

where ?p* specifies a path. Is there a way of doing this?

推荐答案

很正确,您不能在属性路径表达式中使用变量.不过,您可以做一些事情可能会对您有所帮助.

You're right that you can't use variables in property path expressions. There are a few things that you can do, though, that might help you.

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

You can use a wildcard by taking the disjunction of it and its negation, so you can do a simple query that checks whether there is a path connecting two resources:

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

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

If you have a : prefix defined, that can be even shorter, since : is a valid IRI:

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

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

If there is a path (or multiple paths) between two nodes, you can split it up using wildcard paths joined by ?p, and so find all the ?ps that are on the path:

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

我认为,您可以使用空白节点而不是?x?y来缩短该时间:

You can make that even shorter, I think, by using blank nodes instead of ?x and ?y:

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

(不过,可能不起作用.我似乎记得该语法实际上禁止在空白节点内的某些位置使用属性路径.我不确定.)

(That might not work, though. I seem to recall the grammar actually disallowing property paths in some places within blank nodes. I'm not sure.)

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

Now, in the case that there is just one path between two resources, you can even get the properties along that path, along with their positions. You could order by those positions, and then use a group by to concatenate the properties in order into a single string. This is probably easiest to see with an example. Suppose you've got the following data which has a single path from :a to :d:

@prefix : <urn:ex:> .

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

然后,您可以使用类似这样的查询来获取路径中的每个属性及其位置. (不过,这仅在只有一条路径的情况下才有效.请参见我对在SPARQL中?进一步了解它的工作原理.)

Then you can use a query like this to get each property in the path and its position. (This only works if there's a single path, though. See my answer to Is it possible to get the position of an element in an RDF Collection in SPARQL? for a bit more about how this works.)

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来按顺序获取属性的单个字符串. (虽然不能保证保留顺序,但这是很常见的行为.请参阅我对获取protege中的矩阵的回答有关此技术如何工作的另一个示例,并且我的回答到SPARQL 1.1中GROUP_CONCAT中的订购中进行讨论,以讨论为什么不能保证它.)

Now, if you order those results by ?pos and wrap that query in another, then you can use group_concat on ?p to get a single string of the properties in order. (The order being preserved isn't guaranteed, but it's pretty common behavior. See my answer to obtain the matrix in protege for another example of how this technique works, and my answer to Ordering in GROUP_CONCAT in SPARQL 1.1 for discussion about why it is not guaranteed.)

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>" |
-----------------------------------------

这篇关于具有任意属性的SPARQL属性路径查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆