让我们考虑两个类:Person及其子类BlondePerson。 让我们考虑一个关系:isParent,其中一个人是另一个人的父母。 让我们定义关系:isAncestor,其中有一系列isParent关系。
我可能有很多金色人物的祖先。
我的问题:如何编写SPARQL查询,以便了解最接近祖先的金发女郎。如果可能的话,最亲近的意思是我的父母,如果不是祖父母,也不是祖父母等等。
如何为此撰写SPARQL查询?如何确保我会得到最接近的祖先?
谢谢。
答案 0 :(得分:3)
这不太难;您可以使用Is it possible to get the position of an element in an RDF Collection in SPARQL?中演示的相同技术。这个想法基本上是将祖先视为一个序列,你可以从中获得“紧密性”。每个祖先,并从给定的类中选择最近的祖先。如果我们创建一些示例数据,我们最终会得到类似的结果:
@prefix : <urn:ex:>
:a a :Person ; :hasParent :b .
:b a :Person ; :hasParent :c .
:c a :Person, :Blond ; :hasParent :d .
:d a :Person, :Blond ; :hasParent :e .
:e a :Person .
prefix : <urn:ex:>
select distinct
?person
?ancestor
(count(distinct ?mid) as ?closeness)
?isBlond
where {
values ?person { :a }
?a :hasParent+ ?mid .
?mid a :Person .
?mid :hasParent* ?ancestor .
?ancestor a :Person .
bind( if( exists { ?ancestor a :Blond }, true, false ) as ?isBlond )
}
group by ?person ?ancestor ?isBlond
order by ?person ?closeness
-------------------------------------------
| person | ancestor | closeness | isBlond |
===========================================
| :a | :b | 1 | false |
| :a | :c | 2 | true |
| :a | :d | 3 | true |
| :a | :e | 4 | false |
-------------------------------------------
这实际上比我们需要的信息更多,我只是把它包括在内以显示它是如何工作的。现在我们实际上只需要那个?祖先是金发碧眼的,按亲近顺序排列,并将结果限制在第一个(因此也是最接近的):
prefix : <urn:ex:>
select distinct
?person
?ancestor
(count(distinct ?mid) as ?closeness)
where {
values ?person { :a }
?a :hasParent+ ?mid .
?mid a :Person .
?mid :hasParent* ?ancestor .
?ancestor a :Person, :Blond .
}
group by ?person ?ancestor
order by ?person ?closeness
limit 1
---------------------------------
| person | ancestor | closeness |
=================================
| :a | :c | 2 |
---------------------------------