本文介绍了具有任意属性的 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 .

然后您可以使用这样的查询来获取路径中的每个属性及其位置.(不过,这仅在只有一条路径时才有效.请参阅我对 是否可以获取元素在 RDF 集合中的位置的回答)在 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 对这些结果进行排序并将 那个 查询包装在另一个查询中,那么您可以在 上使用 group_concat?p 按顺序获取属性的单个字符串.(不能保证保留的顺序,但这是很常见的行为.请参阅我对 获取 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 属性路径查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-11 18:23