SPARQL:计算出高数据属性值

时间:2017-01-04 11:11:37

标签: sparql rdf semantic-web jena-rules

我有一个问答游戏,学生必须解决化学,英语,物理三个类别的问题。学生将在这些类别中获得积分,例如student1在化学中有50分,在英语中有70分,在物理上有65分。

我可以弄清楚学生在哪个类别中得分最高。但是,我怎样才能获得哪一个是哪个学生拥有的最高分?我的意思是如果一个学生用英语得到90分(没有其他学生得到这个分数),那么我们怎么能算出这个英语的最高分为90分。

请记住:英语分数,化学分数,物理分数是存储在rdf文件中的数据属性。 如果可以使用Jena规则或SPARQL或普通Java代码,我想要。

1 个答案:

答案 0 :(得分:5)

如果我理解正确,您要求在每个类别中找到最高分,然后为每个类别找到该类别中得分最高的学生。使用数据更容易(将来,请尝试提供我们可以使用的最少数据),所以这里有一些示例数据:

@prefix : <urn:ex:>

:student1 :hasScore [ :inCategory :category1 ; :value 90 ] ,
                    [ :inCategory :category2 ; :value 75 ] ,
                    [ :inCategory :category3 ; :value 85 ] .

:student2 :hasScore [ :inCategory :category2 ; :value 75 ] ,
                    [ :inCategory :category3 ; :value 90 ] ,
                    [ :inCategory :category4 ; :value 90 ] .

:student3 :hasScore [ :inCategory :category1 ; :value 85 ] ,
                    [ :inCategory :category2 ; :value 80 ] ,
                    [ :inCategory :category4 ; :value 95 ] .

有四个类别,student1在类别1中得分最高,student3在类别2和4中得分最高,student2在类别3中得分最高。我们可以编写如下查询:

prefix : <urn:ex:>

select ?category ?student ?highScore where {

  #-- Find the high score in each category
  { select ?category (max(?score) as ?highScore) {
      ?student :hasScore [ :inCategory ?category ; :value ?score ] .
    }
    group by ?category
  }

  #-- Then find the student that had that high
  #-- score in the category.
  ?student :hasScore [ :inCategory ?category ; :value ?highScore ] .
}
--------------------------------------
| category   | student   | highScore |
======================================
| :category1 | :student1 | 90        |
| :category2 | :student3 | 80        |
| :category3 | :student2 | 90        |
| :category4 | :student3 | 95        |
--------------------------------------

如果你不关心哪个学生获得最高分,那么你只需要那个内部子查询:

prefix : <urn:ex:>

select ?category (max(?score) as ?highScore) {
  ?student :hasScore [ :inCategory ?category ; :value ?score ] .
}
group by ?category
--------------------------
| category   | highScore |
==========================
| :category1 | 90        |
| :category2 | 80        |
| :category3 | 90        |
| :category4 | 95        |
--------------------------

如果您使用的是不同的属性

在评论中,你问,

  

我的本​​体论是这样的:学生1:英语成绩90;   PhyscicsScore 67; ChemScore 78.同样适用于其他学生。我是不是该   引入像hasScore这样引用英语评分的空白节点,   PhyscicsScore [sic]和ChemScore?

首先,我建议您标准化您的命名约定。首先,请务必使用正确的拼写(例如,物理)。然后,要么缩写要么不要。您将化学缩写为化学,而不是英语缩写为 Eng 。最后,要保持大写一致(例如 EnglishScore ,而不是英语评分)。

没有必要使用我使用的那种表示法。你没有提供样本数据(请将来做),所以我使用了我认为相当容易使用的数据。您的表示似乎不太灵活,但您仍然可以获得所需的信息。这是一些新的样本数据:

@prefix : <urn:ex:>

:student1 :hasCat1Score 90 ;
          :hasCat2Score 75 ;
          :hasCat3Score 85 .

:student2 :hasCat2Score 75 ;
          :hasCat3Score 90 ;
          :hasCat4Score 90 .

:student3 :hasCat1Score 85 ;
          :hasCat2Score 80 ;
          :hasCat4Score 95 .

然后查询只需要为属性使用变量,该变量同时将学生与分数相关联,并且还指示类别。所以你仍然只是按照该属性进行分组并要求获得最高分:

prefix : <urn:ex:>

select ?hasScore (max(?score) as ?highScore) {
  ?student ?hasScore ?score
}
group by ?hasScore
-----------------------------
| hasScore      | highScore |
=============================
| :hasCat1Score | 90        |
| :hasCat2Score | 80        |
| :hasCat3Score | 90        |
| :hasCat4Score | 95        |
-----------------------------