快速回答:这是一个 DBpedia/Virtuoso 错误。
这种情况在演示文稿中有明确描述SPARQL 选项简介作者:朱利安·杜比和卡维莎·斯里尼瓦斯 http://www.slideshare.net/juliandolby/optionals-25419705在第七张幻灯片上,他们使用了一个示例
optional { ?x name ?label }
optional { ?x nick ?label }
对于拥有以下资格的个人name
值,我们永远不会看到任何nick
值,因为optional
模式是左关联的,根据6 包括可选值 http://www.w3.org/TR/sparql11-query/#optionals来自 SPARQL 规范。作者在第八张幻灯片上得出结论:
绑定同一个变量的多个 OPTIONAL 子句很少是您想要的。
您应该首先得到结果optional
匹配的部分。这为变量提供了绑定,所以bound(...)
应该是真的。因此,我认为 DBpedia 的行为是一个错误。
尝试其他实现。
这是一个有趣的行为,我们可以用简单的数据重现它。假设我们有一些这样的数据:
@prefix : <http://stackoverflow.com/q/22478183/1281433/> .
:a :r :x ; :p 2 ; :q 3 .
:b :r :x ; :p 4 ; :q 5 .
然后我们可以使用以下查询并通过 Jena 得到以下结果。我们只得到该房产的结果:p
因为optional
是左关联的,所以上的模式:p
首先涵盖,我们数据中的每个资源都有一个价值:p
.
prefix : <http://stackoverflow.com/q/22478183/1281433/>
select ?x ?v where {
?x :r :x .
optional { ?x :p ?v }
optional { ?x :q ?v }
}
----------
| x | v |
==========
| :b | 4 |
| :a | 2 |
----------
对于耶拿,添加一个filter
不会删除任何结果,我认为这是正确的行为,因为?v
is bound.
prefix : <http://stackoverflow.com/q/22478183/1281433/>
select ?x ?v where {
?x :r :x .
optional { ?x :p ?v }
optional { ?x :q ?v }
filter(bound(?v))
}
----------
| x | v |
==========
| :b | 4 |
| :a | 2 |
----------
工会或财产的救援途径!
上面引用的幻灯片提到您可以使用union
里面的optional
以获得您正在寻找的结果。根据我提供的数据,这意味着您可以执行以下操作:
prefix : <http://stackoverflow.com/q/22478183/1281433/>
select ?x ?v where {
?x :r :x .
optional {
{ ?x :p ?v } union
{ ?x :q ?v }
}
}
----------
| x | v |
==========
| :b | 4 |
| :b | 5 |
| :a | 2 |
| :a | 3 |
----------
这毫无问题,但使用属性路径可以使其更加简洁。如果你真正想要的是绑定?v
的值either the :p
or :q
属性,您可以使用替代属性路径:
prefix : <http://stackoverflow.com/q/22478183/1281433/>
select ?x ?v where {
?x :r :x .
optional { ?x :p|:q ?v }
filter(bound(?v))
}
----------
| x | v |
==========
| :b | 4 |
| :b | 5 |
| :a | 2 |
| :a | 3 |
----------
当然,如果你正在做filter(bound(?v))
,然后是模式?x :p|:q ?v
实际上不再是可选的,因此您可能应该将其移至查询的主要部分:
prefix : <http://stackoverflow.com/q/22478183/1281433/>
select ?x ?v where {
?x :r :x ; :p|:q ?v
}
----------
| x | v |
==========
| :b | 4 |
| :b | 5 |
| :a | 2 |
| :a | 3 |
----------