4

我知道以下针对Wikidata SPARQL Endpoint查询的 SPARQL 毫无意义。从我的应用程序中自动生成一个类似的查询。请忽略概念上的合理性,让我们深入研究正在发生的这件奇怪的事情(至少对我来说)。

SELECT ?year1 ?year_labelTemp
    WHERE
      { 
        ?year1  <http://www.w3.org/2000/01/rdf-schema#label>  ?year_labelTemp .
        { SELECT distinct ?year1
          WHERE
            { ?film  <http://www.wikidata.org/prop/direct/P577>  ?date ;
                     <http://www.wikidata.org/prop/direct/P31>  <http://www.wikidata.org/entity/Q11424>
              BIND(year(?date) AS ?year1)
            }
        }   
      }
    limit 10

根据 SPARQL 中的查询评估,首先评估子查询,然后将其结果投影到包含查询。因此,将首先评估此子查询。

SELECT distinct ?year1
      WHERE
        { ?film  <http://www.wikidata.org/prop/direct/P577>  ?date ;
                 <http://www.wikidata.org/prop/direct/P31>  <http://www.wikidata.org/entity/Q11424>
          BIND(year(?date) AS ?year1)
        }

子查询准确地给出了预期的结果(130 个不同的年份)。然后,这个子查询(?year1变量)的结果将被投影出来并与外部选择中的三重模式连接。

?year1  <http://www.w3.org/2000/01/rdf-schema#label>  ?year_labelTemp .

但是,由于外部选择不应该有任何数据(没有标签?year1),连接不会给出任何结果。

令人惊讶的是(至少对我来说),执行整个查询()首先给出了结果,结果很奇怪。

 wd:Q43576  Mië
 wd:Q221    Masèdonia
 wd:Q221    Республикэу Македоние
 wd:Q221    Republiek van Masedonië
 wd:Q212    Украина
 wd:Q212    Ukraina
 wd:Q212    Украинэ
 wd:Q212    Oekraïne
 wd:Q207    George W. Bush
 wd:Q207    George W. Bush

我错过了什么?

4

2 回答 2

2

问题是有时BIND不能正确投影变量。

您可以使用以下查询进行检查:

SELECT ?year1 ?year_labelTemp ?projected
    WHERE
      { 
        ?year1  rdfs:label  ?year_labelTemp .
        hint:Prior hint:runLast true .
        { SELECT DISTINCT ?year1
          WHERE
            { ?film  wdt:P577  ?date ;
                     wdt:P31 wd:Q11424
              BIND(year(?date) AS ?year1)
              hint:SubQuery hint:runOnce true 
            }
         } 
        BIND(bound(?year1) AS ?projected)
      }
    LIMIT 10

试试看!

幸运的是,以下技巧会有所帮助:

SELECT ?year1 ?year_labelTemp
    WHERE
      { 
        ?year1  rdfs:label  ?year_labelTemp  .
        hint:Prior hint:runLast true .
        { SELECT DISTINCT ?year1
          WHERE
            { ?film  wdt:P577  ?date ;
                     wdt:P31 wd:Q11424
              BIND(year(?date) AS ?year1)
              FILTER (?year1 > 0)
            }
         } 
      }
    LIMIT 10

试试看!


该错误可以在没有嵌套子查询和使用 的情况下重现hint:Query hint:optimizer "None",因此它不应该是查询优化器错误。但有趣的是,在 替换wd:Q11424wd:Q24862.

BLZG-963似乎是最相关的问题(如您所见,也涉及内置函数)。

于 2018-04-28T23:58:01.577 回答
0

您写道,子查询给出了确切的预期结果,但我认为您错过了一个值!有一些未知值的电影作为发布数据,例如 Q18844655(至少在我写这篇文章时)。正是这个空值导致了看似随机的对象被发现。

如果您通过添加例如更改您的内部 SELECT,FILTER(datatype(?date) = xsd:dateTime).您将只获得实际日期,因此只有实际年份,这意味着比没有过滤器的值少一个。在这里试试!

(当使用这个更正的内部 SELECT 时,整个事情都会超时。标签似乎真的不喜欢像这样的奇数值。)

于 2019-07-05T15:12:48.840 回答