SPARQL 查询——最接近的金发前辈

The SPARQL query - the closest blond antecedor

让我们考虑两个 类:Person 及其子类 BlondePerson。 让我们考虑一种关系:isParent,其中一个人是另一个人的 parent。 让我们定义关系:isAncestor,其中有一系列 isParent 关系。

我的祖先可能有很多BlondPersons

我的问题:如何编写 SPARQL 查询以便我了解最近的金发祖先。如果可能的话,最接近的是我的parent,如果不是祖父parent,否则是祖父parent,依此类推。

如何为此编写 SPARQL 查询?如何确保我会找到最接近的祖先?

谢谢。

这并不难;您可以使用 Is it possible to get the position of an element in an RDF Collection in SPARQL? 中演示的相同技术。这个想法本质上是将祖先视为一个序列,从中你可以得到每个祖先的 "closeness",以及距离给定 class 最近的祖先 select。如果我们创建一些样本数据,我们最终会得到这样的结果:

@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   |
-------------------------------------------

这实际上比我们需要的信息更多,我只是将其包括在内以展示其工作原理。现在我们实际上可以只要求 ?ancestor 是金发,按接近程度排序,并将结果限制为第一个(因此最接近):

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         |
---------------------------------