让我们使用这些数据:
@prefix example: <http://example.org/> .
example:subject1 example:property example:object1 .
example:subject1 example:property example:object2 .
没有属性路径
像这样的查询会产生?subjects
两个不同的值example:property
:
prefix example: <http://example.org/>
select ?subject where {
?subject example:property ?object1, ?object2 .
filter ( ?object1 != ?object2 )
}
--------------------
| subject |
====================
| example:subject1 |
| example:subject1 |
--------------------
不过,这几乎是您已经拥有的。要将其归结为一个结果,您可以select distinct
:
prefix example: <http://example.org/>
select distinct ?subject where {
?subject example:property ?object1, ?object2 .
filter ( ?object1 != ?object2 )
}
--------------------
| subject |
====================
| example:subject1 |
--------------------
关于属性路径
属性路径是一种表达属性链(向前和向后)的方式,无需沿途绑定所有单独的资源,如果要允许可变数量的边,这一点尤其重要。您可以绑定链两端的东西,但不能绑定中间的东西。
数据以图形方式显示如下:
示例:对象 1 ←示例:属性示例:主题 →示例:属性示例:对象2
如果要选择与某个主题相关的两个对象,可以使用属性路径。example:object1
从to的路径example:object2
是(^example:property)/example:property
,因为您沿着一条example:property
边向后到达example:subject
,然后沿着一条example:property
边向前到达example:object2
。如果您想要对象而不是主题,则可以使用以下查询:
prefix example: <http://example.org/>
select * where {
?object1 (^example:property)/example:property ?object2 .
filter ( ?object1 != ?object2 )
}
我认为没有一种方便的方法可以使用属性路径获取主题。你可以做类似的事情
?subject property/^property/property/^property ?subject
从?subject
到某个对象,然后返回到某个对象(即,不一定是?subject
,然后再出来,然后回到?subject
,但是您不会再得到有两个不同对象的保证。
SPARQL 属性路径的路径语言在 SPARQL 1.1 查询语言推荐(W3C 标准)的第9.1 部分属性路径语法中进行了描述。值得注意的是,它不包括早期工作草案的第 3 节路径语言p{n}
所做的符号。这意味着你的模式
?subject example:property{2} ?object
实际上不是合法的 SPARQL(尽管某些实现可能支持它)。但是,根据工作草案,我们仍然可以确定它的含义。要匹配此模式,您需要表单的数据
?subject → example:property [] → example:property ?object
其中[]
只是表示一些任意资源。这与您实际获得的数据不同。因此,即使此语法在 SPARQL 1.1 中是合法的,它也不会为您提供您正在寻找的结果类型。一般来说,属性路径本质上是数据中属性链的一种正则表达式。
结论
虽然属性链可以使某些事情变得非常好,而使某些原本不可能的事情成为可能(例如,请参阅我对Is it possible to get the position of an element in an RDF Collection in SPARQL? 的回答),但我不认为他们重新适合这种情况。我认为您最好的选择和相当优雅的解决方案是:
?subject example:property ?object1, ?object2 .
filter( ?object1 != ?object2 ).
因为它最清楚地捕获了预期的查询,“找到?subject
具有两个不同值的 s example:property
。”</p>