缩小SPARQL查询

时间:2016-04-15 12:41:30

标签: sparql rdf owl ontology

我想创建一个只返回person1(David)和person2(Charles)一起出现的项目的查询。

我的查询是:

SELECT ?item ?par ?mod ?hon ?firstName ?lastName
WHERE {
    ?item   sci:itemTitle ?title.
    {?item sci:hasParticipant ?par. {?par sci:firstName "Charles".}UNION{?par sci:firstName "David".}} 
    UNION {?item sci:hasModerator ?mod. {?mod sci:firstName "Charles".}UNION{?mod sci:firstName "David".}} 
    UNION {?item sci:hasGuestOfHonor ?hon. {?hon sci:firstName "Charles".}UNION{?hon sci:firstName "David".}}
}

我的结果显示在这里:

results

只有两次出现,其中person1和person2一起出现(程序项目4和6)。我怎样才能缩小查询范围以获得我想要的内容,或者有更好的方法来完成我的工作?

1 个答案:

答案 0 :(得分:3)

union 用于表达替代方案。每当你说 {x} union {y} 时,你都要求匹配 x y (或两者)持有。既然您正在寻找两个人都参与的案例(不是任何一个人),那么您不想使用 union 。据我所知,一个人可以通过三种方式参与项目:他们可以是参与者,主持人或荣誉嘉宾。你可以将其压缩成:

?item sci:hasModerator|sci:hasParticipant|sci:hasGuestofHonor ?person

模式?ax | y | z?b 表示?a 通过连接到?b x y z 。这是一条交替的道路。您可以在SPARQL 1.1规范§9 Property Paths中阅读有关属性路径的更多信息。

然后,你希望有两个人,所以:

?item sci:hasModerator|sci:hasParticipant|sci:hasGuestofHonor ?person1, ?person2

会给你两个人(或者可能是同一个人,但是当我们检查姓名时,我们会强制他们拥有我们想要的名字,这应该要求他们是不同的人,或者至少是一个人两个名字)。模式?ap?b,?c 表示?a p 相关联到 ?b ?c

最后,你希望一个人拥有名字Charles和另一个David,所以我们只需要添加

?person1 sci:firstName "Charles" .
?person2 sci:firstName "David" .

由于您实际上并未将?person1 ?person2 的值用于其他任何内容,因此您也可以在此处使用空白节点。例如,

?item sci:hasModerator|sci:hasParticipant|sci:hasGuestofHonor [ sci:firstName "Charles" ] ,  [ sci:firstName "David" ] .

让我们看看它们是如何组合在一起的。我根据您显示的结果创建了一些示例数据。显然,它与您的数据不同,但它足以重现您展示的结果,并展示其工作原理。

prefix sci: <urn:ex:>

sci:Male_Person2 sci:firstName "David" .
sci:Male_Person3 sci:firstName "Charles" .

sci:ProgrammeItem1 sci:itemTitle "" ;
                   sci:hasParticipant sci:Male_Person3 ;
                   sci:hasModerator sci:Male_Person3 .
sci:ProgrammeItem3 sci:itemTitle "" ;
                   sci:hasParticipant sci:Male_Person2 ;
                   sci:hasModerator sci:Male_Person2 .
sci:ProgrammeItem4 sci:itemTitle "" ;
                   sci:hasParticipant sci:Male_Person3 ;
                   sci:hasModerator sci:Male_Person2 .
sci:ProgrammeItem6 sci:itemTitle "" ;
                   sci:hasParticipant sci:Male_Person2, sci:Male_Person3 .
prefix sci: <urn:ex:>

select ?item {
    ?item sci:itemTitle ?title .
    ?item sci:hasModerator|sci:hasParticipant|sci:hasGuestofHonor
      [ sci:firstName "Charles" ] ,
      [ sci:firstName "David" ] .
}
----------------------
| item               |
======================
| sci:ProgrammeItem4 |
| sci:ProgrammeItem6 |
----------------------