【问题标题】:Why is this SPARQL query not returning any results?为什么这个 SPARQL 查询没有返回任何结果?
【发布时间】:2014-03-18 11:36:47
【问题描述】:

通过DBpedia SPARQL endpoint 运行此查询会得到很多结果(填充了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)) 会返回一个空结果集:

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 结果,但没有任何结果。

【问题讨论】:

  • 我看到你已经接受了一个答案,但我希望你能看看我提供的第二个答案。我认为“变量绑定和未绑定”的想法是不正确的,规范说你应该得到结果。即,我认为这是一个 DBpedia/Virtuoso 错误。此外,使用union 或属性路径,您可以使用比已接受答案中给出的更简单的查询可靠地获得所需的结果。
  • “绑定和未绑定”是为了说明行为可能是如何发生的。我绝不是说这是规范的标准行为。我也怀疑一个错误,但没有时间深入挖掘。

标签: rdf sparql dbpedia virtuoso


【解决方案1】:

快速回答:这是一个 DBpedia/Virtuoso 错误。

幻灯片七的演示文稿An Introduction to SPARQL Optionals by Julian Dolby and Kavitha Srinivas 明确描述了这种情况,其中他们使用了一个示例

optional { ?x name ?label }
optional { ?x nick ?label }

对于具有name 值的个人,我们永远不会看到任何nick 值,因为根据SPARQL 规范中的6 Including Optional Valuesoptional 模式是关联的。作者在幻灯片 8 中得出结论:

绑定同一个变量的多个 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 |
----------

对于 Jena,添加 filter 不会删除任何结果,我认为这是正确的行为,因为 ?v 绑定的。

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 或 Property 的救援路径!

上面引用的幻灯片提到您可以在optional 中使用union 来获得您正在寻找的结果。根据我提供的数据,这意味着您可以这样做:

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 绑定到:p: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 |
----------

【讨论】:

  • 该属性路径替代方案很有创意。 +1
  • @Kristian 带有属性路径和values,很容易摆脱大量union 用例。例如,你想要 frobbed 或 quexed Foo 或 Bar 的东西? values ?type { :Foo :Bar } ?thing :frobbed|:quuxed [ a ?type ] . 它使许多查询非常变得更简单。 :)
  • 这很整洁。我将尝试将这些融入我的工作中
  • @Kristian 是的,我现在真的有点希望对象和主题也有更简单的交替语法。毕竟,从values ?type { :Foo :Bar } values ?p { :frobbed :quuxed } ?thing ?p [ a ?type ] 到我在上一条评论中写的内容很容易。为什么我们也不能有?thing :frobbed|:quuxed [ a :Foo|:Bar ]
  • 我喜欢。您应该在 sparql 1.x+ 规范中提出这个建议。有人可能会喜欢你的想法。 w3.org/standards/techs/sparql#w3c_all
【解决方案2】:

罪魁祸首是同一变量 (?institution) 上的双重 OPTIONAL。可能发生的情况是,恰好一个 OPTIONAL 总是成功,这意味着另一个总是失败 - 所以 ?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

【讨论】:

  • 这是否也可以通过使用单个 optional 但具有备用属性路径:optional { ?person dbpprop:workInstitution|dbpprop:workInstitutions ?institution } 来解决?
  • 好主意,好像也可以这样解决,我现在试了下,也返回12161结果。
【解决方案3】:

是的,这个案子应该得到解决。编译后的 SQL 包含两项检查,一项针对来自第一个 OPTIONAL 的 ?institution,一项针对来自第二个 OPTIONAL 的 ?institution。形式上正确的编译应该是在其输出上带有过滤器的嵌套子查询或 FITLER (bound (?institution_1) || bound (?institution_2)) 。真正合适的编译器应该报告关于奇怪查询的警告,但 SPARQL 协议不支持警告:|

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-24
    • 1970-01-01
    相关资源
    最近更新 更多