获取传递关系中的所有节点

时间:2010-10-29 21:21:42

标签: rdf sparql

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

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

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

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

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

3 个答案:

答案 0 :(得分: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?easternmost以东点以西的点的IRI(实际上包括?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 xy z其中价值是递增的?有可能做到两个......

答案 1 :(得分:2)

据我所知,您不能将元素的变量列表作为SPARQL解决方案。我认为最简单的方法就是从?a g:eastOf ?b获取对(a,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中的传递性将为您提供 start end 节点,但您将失去所有中间点的可跟踪性。

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

编辑指向Jena + owl:TransitiveProperty

首先请确保将带有以下公理的本体加载到Jena Model

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。它也可以完成这项工作。

让我们知道它是否有效,或者如果你遇到任何问题,欢呼!!!

答案 2 :(得分:0)

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