在SPARQL

时间:2017-12-29 14:03:11

标签: sparql

我将在这里使用通用术语。

我有一组对象,每个对象都有多个属性将它们链接到主题。 Subject有一个通过另一个属性与之关联的整数值。

对于每个对象,我想以最大值检索其主题。

根据以下内容检索具有一个对象的最大值的主题非常简单:How do I make a SPARQL query to find the highest value for a property?。由于我想要主题本身(而不仅仅是它的价值),我使用了“获取所有主题,订购它们,限制1 ”的解决方案。

但是,我不能让这种方法适用于多个对象。我试过了:

SELECT ?object ?subject ?subMaxVal
WHERE {
  ?object a :Object.

  {
    SELECT ?subject (?value as ?subMaxVal)
    WHERE {
      ?object :Predicate ?subject.
      ?subject :value ?value.  
    }
    ORDER BY DESC(?value)
    LIMIT 1
  }
}

但这会返回不正确的结果。它找到?subMaxVal的值,但随后使用数据集中的所有对象返回此值(即使此值仅适用于其中一个)。

我发现提到SPARQL子查询是在内部优先执行的。我无法解决如何构建查询以执行每个对象的子查询。

1 个答案:

答案 0 :(得分:4)

我们的想法是先使用子SELECT来获取每个对象的最大值。然后在外部查询中,此最大值用于获取主题:

样本数据

@prefix : <http://ex.org/> .
:o1 :Predicate :s1 ; a :Object . :s1 :value 1 .
:o1 :Predicate :s2 ; a :Object . :s2 :value 2 .
:o1 :Predicate :s3 ; a :Object . :s3 :value 3 .
:o2 :Predicate :s2 ; a :Object . :s2 :value 2 .
:o2 :Predicate :s3 ; a :Object . :s3 :value 3 .
:o3 :Predicate :s2 ; a :Object . :s2 :value 2 .
:o3 :Predicate :s3 ; a :Object . :s3 :value 3 .
:o3 :Predicate :s4 ; a :Object . :s4 :value 3 .

查询

PREFIX : <http://ex.org/>
SELECT ?object ?subject ?subMaxVal
WHERE {
  ?object a :Object.
  ?object :Predicate ?subject.
  ?subject :value ?subMaxVal.  

  # find the max value per object
  {
    SELECT ?object (MAX(?value) as ?subMaxVal)
    WHERE {
      ?object :Predicate ?subject.
      ?subject :value ?value.  
    }
    GROUP BY ?object
  }
}

输出

--------------------------------
| object | subject | subMaxVal |
================================
| :o2    | :s3     | 3         |
| :o3    | :s4     | 3         |
| :o3    | :s3     | 3         |
| :o1    | :s3     | 3         |
--------------------------------

如您所见,如果这些主题共享最大值,则此查询确实会返回单个对象的多个主题。值。在这种情况下,您可以获得这些主题的样本:

查询

PREFIX : <http://ex.org/>
SELECT ?object (MIN(?subj) as ?subject) ?subMaxVal
WHERE {
  ?object a :Object.
  ?object :Predicate ?subj.
  ?subj :value ?subMaxVal.  

  # find the max value per object
  {
    SELECT ?object (MAX(?value) as ?subMaxVal)
    WHERE {
      ?object :Predicate ?subject.
      ?subject :value ?value.  
    }
    GROUP BY ?object
  }
}
GROUP BY ?object ?subMaxVal

输出

--------------------------------
| object | subject | subMaxVal |
================================
| :o1    | :s3     | 3         |
| :o3    | :s3     | 3         |
| :o2    | :s3     | 3         |
--------------------------------