以某种方式可以通过与SPARQL的传递关系获得连接的节点列表吗? 我有以这种方式连接的元素:
?a g:eastOf ?b
?b g:eastOf ?c
…
并非所有节点都相互连接,因为有些节点更向南。仅当节点垂直位于同一平面中时,才可能存在g:eastOf
关系。这意味着有几组节点没有相互连接。
我想得到所有这些节点组(基本上是一个列表列表)。有没有办法在SPARQL中做到这一点? SELECT
语句需要有限数量的变量,并且不能以某种方式表达“某个列表”。
我只对所有节点的xsd:integer
属性从西向东升序的列表感兴趣,但是在我得到第一个问题的解决方案后,这应该相对容易。
答案 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 x
和y 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查询中的自定义语法。