是否可以在 SPARQL 中获取 RDF 集合中元素的位置? [英] Is it possible to get the position of an element in an RDF Collection in SPARQL?

查看:37
本文介绍了是否可以在 SPARQL 中获取 RDF 集合中元素的位置?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有以下 Turtle 声明:

Suppose that I have the following Turtle declaration:

@prefix : <http://example.org#> .

:ls :list (:a :b :c)

有没有办法获取集合中元素的位置?

Is there a way to get the positions of the elements in the collection?

例如,使用此查询:

PREFIX :     <http://example.org#>
PREFIX rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#> 

SELECT ?elem WHERE {
 ?x :list ?ls .
 ?ls rdf:rest*/rdf:first ?elem .
}

我明白了:

--------
| elem |
========
| :a   |
| :b   |
| :c   |
--------

但我想获得一个查询:

--------------
| elem | pos |
==============
| :a   |  0  |
| :b   |  1  |
| :c   |  2  |
--------------

有可能吗?

推荐答案

纯 SPARQL 1.1 解决方案

我扩展了数据以使问题变得更难.让我们向列表中添加一个重复的元素,例如,在末尾添加一个 :a:

@prefix : <http://example.org#> .

:ls :list (:a :b :c :a) .

然后我们可以使用这样的查询来提取每个列表节点(及其元素)以及该节点在列表中的位置.这个想法是,我们可以用类似 [] :list/rdf:rest* ?node 的模式匹配列表中的所有单个节点.但是,每个节点的位置是列表头和?node之间的中间节点数.我们可以通过将模式分解为

Then we can use a query like this to extract each list node (and its element) along with the position of the node in the list. The idea is that we can match all the individual nodes in the list with a pattern like [] :list/rdf:rest* ?node. The position of each node, though, is the number of intermediate nodes between the head of the list and ?node. We can match each of those intermediate nodes by breaking the pattern down into

[] :list/rdf:rest* ?mid . ?mid rdf:rest* :node .

那么如果我们按?node分组,不同的?mid绑定的数量就是?node在列表中的位置.因此,我们可以使用以下查询(它也获取与每个节点关联的元素(rdf:first))来获取元素在列表中的位置:

Then if we group by ?node, the number of distinct ?mid bindings is the position of ?node in the list. Thus we can use the following query (which also grabs the element (the rdf:first) associated with each node) to get the positions of elements in the list:

prefix : <https://stackoverflow.com/q/17523804/1281433/>
prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

select ?element (count(?mid)-1 as ?position) where { 
  [] :list/rdf:rest* ?mid . ?mid rdf:rest* ?node .
  ?node rdf:first ?element .
}
group by ?node ?element

----------------------
| element | position |
======================
| :a      | 0        |
| :b      | 1        |
| :c      | 2        |
| :a      | 3        |
----------------------

这是可行的,因为 RDF 列表的结构是这样的链表(其中 ?head 是列表的开头(:list 的对象),并且是 ?mid 的另一个绑定,因为模式 [] :list/rdf:rest* ?mid):

This works because the structure of an RDF list is a linked list like this (where ?head is the beginning of the list (the object of :list), and is another binding of ?mid because of the pattern [] :list/rdf:rest* ?mid):

问题的提问者还发布了一个答案,该答案使用 Jena 的 ARQ 扩展来处理 RDF 列表.该答案中发布的解决方案是

The asker of the question also posted an answer that uses Jena's ARQ extensions for working with RDF lists. The solution posted in that answer is

PREFIX :     <http://example.org#>
PREFIX rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#> 
PREFIX list: <http://jena.hpl.hp.com/ARQ/list#>

SELECT ?elem ?pos WHERE {
 ?x :list ?ls .
 ?ls list:index (?pos ?elem).
}

这个答案取决于使用 Jena 的 ARQ 并启用扩展,但它更简洁和透明.不明显的是,一个人是否有明显更优的表现.事实证明,对于小列表,差异并不是特别显着,但对于较大的列表,ARQ 扩展具有更好的性能.纯 SPARQL 查询的运行时间很快变得非常长,而使用 ARQ 扩展的版本几乎没有区别.

This answer depends on using Jena's ARQ and enabling the extensions, but it is more concise and transparent. What isn't obvious is whether one has an obviously preferable performance. As it turns out, for small lists, the difference isn't particularly significant, but for larger lists, the ARQ extensions have much better performance. The runtime for the pure SPARQL query quickly becomes prohibitively long, while there's almost no difference in the version using the ARQ extensions.

-------------------------------------------
| num elements | pure SPARQL | list:index |
===========================================
|      50      |    1.1s     |    0.8s    |
|     100      |    1.5s     |    0.8s    |
|     150      |    2.5s     |    0.8s    |
|     200      |    4.8s     |    0.8s    |
|     250      |    9.7s     |    0.8s    |
-------------------------------------------

这些特定值显然会因您的设置而异,但在任何地方都应该可以观察到总体趋势.由于未来情况可能会发生变化,以下是我正在使用的特定版本的 ARQ:

These specific values will obviously differ depending on your setup, but the general trend should be observable anywhere. Since things could change in the future, here's the particular version of ARQ I'm using:

$ arq --version
Jena:       VERSION: 2.10.0
Jena:       BUILD_DATE: 2013-02-20T12:04:26+0000
ARQ:        VERSION: 2.10.0
ARQ:        BUILD_DATE: 2013-02-20T12:04:26+0000

因此,如果我知道我必须处理非平凡大小的列表并且我有可用的 ARQ,我会使用扩展.

As such, if I knew that I had to process lists of non-trivial sizes and that I had ARQ available, I'd use the extension.

这篇关于是否可以在 SPARQL 中获取 RDF 集合中元素的位置?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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