Rdf 为什么这个SPARQL查询不返回任何结果?
通过运行此查询将获得许多结果(填充了Rdf 为什么这个SPARQL查询不返回任何结果?,rdf,sparql,dbpedia,virtuoso,Rdf,Sparql,Dbpedia,Virtuoso,通过运行此查询将获得许多结果(填充了institution列): 但是,添加行过滤器(绑定(?机构))将返回一个空结果集: select ?person ?field ?institution where { ?person a dbpedia-owl:Agent . OPTIONAL { ?person dbpprop:workInstitution ?institution . } OPTIONAL { ?person dbpprop:workInstitutions ?in
institution
列):
但是,添加行过滤器(绑定(?机构))
将返回一个空结果集:
select ?person ?field ?institution where
{
?person a dbpedia-owl:Agent .
OPTIONAL { ?person dbpprop:workInstitution ?institution . }
OPTIONAL { ?person dbpprop:workInstitutions ?institution .}
?person dbpprop:field ?field .
FILTER(BOUND(?institution))
}
为什么会这样?我希望第一次查询的所有结果都会显示
机构
结果,但没有结果显示。罪魁祸首是同一变量(?机构
)上的双可选
)。可能发生的情况是,只有一个选项总是成功,这意味着另一个选项总是失败-因此?institution
变量总是绑定的,而不是绑定的:)
例如,您可以通过以下查询来解决此问题:
select ?person ?field ?institution
{
?person a dbpedia-owl:Agent .
OPTIONAL { ?person dbpprop:workInstitution ?inst . }.
OPTIONAL { ?person dbpprop:workInstitutions ?insts . }.
BIND (IF(bound(?inst), ?inst, ?insts) AS ?institution )
?person dbpprop:field ?field .
filter(bound(?institution)).
}
它检查哪个案例成功,并将其绑定到结果变量?institution
快速回答:这是一个DBpedia/Virtuoso错误。
幻灯片7中的演示中明确描述了这种情况,其中他们使用了
optional { ?x name ?label }
optional { ?x nick ?label }
对于具有名称
值的个人,我们永远不会看到任何尼克
值,因为根据SPARQL规范,可选
模式是左关联的。作者在第八张幻灯片上得出结论:
绑定同一变量的多个可选子句很少是您想要的
您应该获得匹配的第一个可选零件的结果。这为变量提供了绑定,因此bound(…)
应该为true。因此,我认为DBpedia的行为是一个bug
使用其他实现进行实验。
这是一个有趣的行为,我们可以用简单的数据重现它。假设我们有如下数据:
@prefix : <http://stackoverflow.com/q/22478183/1281433/> .
:a :r :x ; :p 2 ; :q 3 .
:b :r :x ; :p 4 ; :q 5 .
对于Jena,添加过滤器
不会删除任何结果,我认为这是正确的行为,因为?v
是绑定的
联盟或财产拯救之路!
上面引用的幻灯片提到,您可以在可选
中使用联合
,以获得所需的结果。根据我提供的数据,这意味着您可以:
prefix : <http://stackoverflow.com/q/22478183/1281433/>
select ?x ?v where {
?x :r :x .
optional {
{ ?x :p ?v } union
{ ?x :q ?v }
}
}
这样做没有问题,但使用属性路径可以使其更加简洁。如果您真正想要的是将?v
绑定到:p
或:q
属性的值,则可以使用替代属性路径:
prefix : <http://stackoverflow.com/q/22478183/1281433/>
select ?x ?v where {
?x :r :x .
optional { ?x :p|:q ?v }
filter(bound(?v))
}
当然,如果您正在执行筛选(绑定(?v))
,则模式?x:p |:q?v
实际上不再是可选的,因此您可能应该将其移动到查询的主要部分:
prefix : <http://stackoverflow.com/q/22478183/1281433/>
select ?x ?v where {
?x :r :x ; :p|:q ?v
}
是的,这个箱子应该是固定的。编译后的SQL包含两个检查,一个检查来自第一个可选的?机构,另一个检查来自第二个可选的?机构。形式上正确的编译应该是输出端带有过滤器的嵌套子查询或FITLER(bound(?institution_1)| bound(?institution_2))。真正合适的编译器应该报告关于奇怪查询的警告,但是SPARQL协议不支持警告:|这也可以通过使用一个可选的来解决,但是使用一个可选的属性路径:可选的{person dbpprop:workInstitution | dbpprop:workInstitutions?institution}
好主意,似乎它也可以这样解决,我现在尝试了这个查询,它还返回12161
结果。我看到您已经接受了一个答案,但我希望您能看看我提供的第二个答案。我认为“变量是绑定的和未绑定的”的想法是不正确的,规范说应该返回结果。也就是说,我认为这是一个DBpedia/Virtuoso bug。此外,使用union
或属性路径,使用比接受答案中给出的查询简单得多的查询,您可以可靠地获得所需的结果。我决不是说这是规范中的标准行为。我也怀疑有一个bug,但没有时间深入挖掘。这个属性路径选择很有创意+1@Kristian有了属性路径和值
,就很容易摆脱大量的联合
用例。比如说,你想要的东西在食物或酒吧里被弄脏或弄脏了<代码>值?类型{:Foo:Bar}?对象:frobbed |:quoxed[a?type]。
它使许多查询更简单。:)那太好了。我要试着把这些融入我的生活stuff@Kristian是的,我现在真的有点希望对象和主题也有一个更简单的交替语法。毕竟,从values?type{:Foo:Bar}values?p{:frobbed:quxed}?thing?p[a?type]
到我在前面的评论中写的东西很容易。为什么我们不能有?东西:frobbed |:quoxed[a:Foo |:Bar]
?我喜欢它。您应该在sparql 1.x+规范中提出这一点。有人可能会喜欢你的想法。
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 |
----------
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 |
----------
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 |
----------
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 |
----------