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 |
----------