我想创建一个只返回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".}}
}
我的结果显示在这里:
只有两次出现,其中person1和person2一起出现(程序项目4和6)。我怎样才能缩小查询范围以获得我想要的内容,或者有更好的方法来完成我的工作?
答案 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 |
----------------------