5

是否有可能通过与 SPARQL 的传递关系获得连接的节点列表?我有以这种方式连接的元素:

?a g:eastOf ?b
?b g:eastOf ?c
…

并非所有节点都相互连接,因为有些节点位于更南端。只有当节点垂直位于同一平面时,才可能存在g:eastOf关系。这意味着有几组节点彼此不连接。

我想获得所有这些节点组(基本上是列表列表)。有没有办法在 SPARQL 中做到这一点?该SELECT语句需要有限数量的变量,并且不能以某种方式表达“列表”某些东西。

我只对xsd:integer从西到东时所有节点的属性都在上升的列表感兴趣,但是在我解决了我的第一个问题之后,这应该相对容易。

4

3 回答 3

5

您至少可以使用 SPARQL 1.1 完成其中的一些操作。

获取节点列表

假设您有数据,其中有两组点基于 形成一行:eastOf

@prefix : <http://stackoverflow.com/q/4056008/1281433/>

:a :eastOf :b .
:b :eastOf :c .
:c :eastOf :d .

:e :eastOf :f .
:f :eastOf :g .
:g :eastOf :h .

然后你可以使用这样的查询:

prefix : <http://stackoverflow.com/q/4056008/1281433/>

select (group_concat(strafter(str(?westernpoint),str(:));separator=", ") as ?colatitudinalPoints)
 where {
  ?easternmost :eastOf* ?westernpoint .
  filter not exists { ?easternmoster :eastOf ?easternmost }
}
group by ?easternmost

得到这些结果:

-----------------------
| colatitudinalPoints |
=======================
| "e, f, g, h"        |
| "a, b, c, d"        |
-----------------------

有一些字符串处理

group_concat(strafter(str(?westernpoint),str(:));separator=", ") as ?colatitudinalPoints

你可能不需要的;关键是它?westernpoint以东以西的点的IRI ?easternmost(实际上包括?easternmost,因为我们*在属性路径中使用过),然后我们需要以某种方式将它们连接在一起。在这里,我做了一些字符串处理以使结果更漂亮。你可以很容易地做到

prefix : <http://stackoverflow.com/q/4056008/1281433/>

select (group_concat(?westernpoint;separator=", ") as ?colatitudinalPoints)
 where {
  ?easternmost :eastOf* ?westernpoint .
  filter not exists { ?easternmoster :eastOf ?easternmost }
}
group by ?easternmost

并得到

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| colatitudinalPoints                                                                                                                                                                      |
============================================================================================================================================================================================
| "http://stackoverflow.com/q/4056008/1281433/e, http://stackoverflow.com/q/4056008/1281433/f, http://stackoverflow.com/q/4056008/1281433/g, http://stackoverflow.com/q/4056008/1281433/h" |
| "http://stackoverflow.com/q/4056008/1281433/a, http://stackoverflow.com/q/4056008/1281433/b, http://stackoverflow.com/q/4056008/1281433/c, http://stackoverflow.com/q/4056008/1281433/d" |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

确保节点上升

您的其他要求更具挑战性:

我只对从西向东移动时所有节点的 xsd:integer 属性上升的列表感兴趣,但是在我找到第一个问题的解决方案后,这应该相对容易。

也就是说,如果你能在类似的情况下明确你想要什么

w --eastof-> x --eastof-> y --eastof-> z
|            |            |            |
5            6            2            3

例如,你想拒绝整个链,因为节点不是全部升序,还是你想获得两个子链w x并且y z其中的值是升序的?可能两者都可以……</p>

于 2013-11-27T17:35:05.793 回答
2

据我所知,您无法将元素的可变列表作为 SPARQL 解决方案。我认为做你需要的最简单的方法就是从中获取对 (a,b)?a g:eastOf ?b并对它们进行排序。

SELECT ?a ?b WHERE {
?a g:eastOf ?b
} ORDER BY ASC(?a) ASC(?b)

放置一些逻辑来转换元素列表上的元组列表应该非常简单。

如果您使用具有传递性的推理,您将无法追溯连接 A 和 C 的路径。如果您有类似 (A,g:eastOf,B) 和 (B,g:eastOf,C) 之类的东西。基本上在这种情况下,使用推理会使事情变得更加复杂,因为您想要构建连接元素的完整列表。SPARQL 中的传递性将为您提供起点终点节点,但您将失去所有中间点的可追溯性。

如果您没有数百万条语句,我认为上面的 SPARQL 查询加上一些转换结果集的逻辑就可以完成这项工作。

编辑以指向 Jena + owl:TransitiveProperty

因此,首先确保将具有以下公理的本体加载到Jena 模型中:

g:eastOf rdf:type owl:TransitiveProperty .

然后启用 Jena OWL 推理器,请参阅此处的文档: Jena OWL coverage

并将Jena ARQ连接到您的模型,以便能够启动 SPARQL 查询。

一旦你这样做了......如果你有类似......

:x g:eastOf :y .
:y g:eastOf :t .
:t g:eastOf :z .

然后你运行一个查询......

SELECT ?a ?b WHERE {
?a g:eastOf ?b
} ORDER BY ASC(?a) ASC(?b)

你会得到 ...

:x g:eastOf :y .
:x g:eastOf :t .
:x g:eastOf :z .
:y g:eastOf :t .
:y g:eastOf :z .
(...)

还与 Jena 一起考虑使用Property Paths。它也会完成这项工作。

让我们知道它是否有效,或者如果您遇到任何问题,干杯!!!

于 2010-10-30T09:37:11.890 回答
0

OpenLink Virtuoso 支持这样的事情: SPARQL 中的传递性这需要 SPARQL 查询中的自定义语法。

于 2010-10-30T08:22:50.490 回答