SPARQL 查询根据语句的顺序返回不同的结果

Posted

技术标签:

【中文标题】SPARQL 查询根据语句的顺序返回不同的结果【英文标题】:SPARQL query returns different results depending on the order of statements 【发布时间】:2018-01-10 13:39:47 【问题描述】:

我有一个 SPARQL 查询,它返回两个资源中最具体的常见类。

当我尝试在 https://dbpedia.org/sparql 上运行它时,有时它什么也不返回,而有时它返回我想要的类。

我注意到它与查询中语句的顺序有关。

这不是一个理想的行为,因为当我执行查询时,无论我输入资源 URI 的顺序如何,我都希望它具有相同的结果。

有没有人遇到过这个问题并找到了解决方案?

查询

以下查询正常运行,返回 http://dbpedia.org/ontology/Film 和 http://dbpedia.org/ontology/Wikidata:Q11424 作为结果:

SELECT ?lcs
WHERE

  <http://dbpedia.org/resource/Ice_Age_(2002_film)> a ?class1 .
  ?class1 rdfs:subClassOf* ?lcs .
  <http://dbpedia.org/resource/Finding_Nemo> a ?class2 .
  ?class2 rdfs:subClassOf* ?lcs .

  FILTER NOT EXISTS 
    <http://dbpedia.org/resource/Finding_Nemo> a ?class3 .
    ?class3 rdfs:subClassOf* ?sublcs .
    <http://dbpedia.org/resource/Ice_Age_(2002_film)> a ?class4 .
    ?class4 rdfs:subClassOf* ?sublcs .
    ?sublcs  rdfs:subClassOf ?lcs
  

  FILTER strstarts(str(?lcs), "http://dbpedia.org/ontology")

但是,以下查询不返回任何内容:

SELECT ?lcs
WHERE

  <http://dbpedia.org/resource/Finding_Nemo> a ?class1 .
  ?class1 rdfs:subClassOf* ?lcs .
  <http://dbpedia.org/resource/Ice_Age_(2002_film)> a ?class2 .
  ?class2 rdfs:subClassOf* ?lcs .

  FILTER NOT EXISTS 
    <http://dbpedia.org/resource/Finding_Nemo> a ?class3 .
    ?class3 rdfs:subClassOf* ?sublcs .
    <http://dbpedia.org/resource/Ice_Age_(2002_film)> a ?class4 .
    ?class4 rdfs:subClassOf* ?sublcs .
    ?sublcs  rdfs:subClassOf ?lcs
  

  FILTER strstarts(str(?lcs), "http://dbpedia.org/ontology")

【问题讨论】:

由于某些原因,第二次查询成本更高,Virtuoso 在查询执行时间内无法找到您想要的。但是出于什么原因...我猜原因是 Finding Nemordf:types 的数量(~55)超过了 Ice 的rdf:types 的数量年龄 (~35)。顺便说一下,您的查询的 SQL 执行计划略有不同(请查看生成 SPARQL 编译报告(而不是执行查询) 以查看它们)。 别忘了 Virtuoso 有 anytime 功能,网页界面的默认超时时间是 30 秒。 正如 StansilavKralin 所说,虽然在语义上是等价的,但三元组模式的不同顺序可能会导致不同的查询执行计划。顺便说一句,这是一家三合店中最困难的部分,找到“最好的”并非易事(即使它甚至存在) 顺便说一句,您还可以在NOT EXISTS 部分添加过滤器FILTER strstarts(str(?sublcs), "http://dbpedia.org/ontology"),因为您只对DBpedia 本体感兴趣。 或者更高效的应该是在查询的第一部分使用?lcs a owl:Class .。只有 DBpedia 类才加载这些模式三元组。 【参考方案1】:

    您正在公共端点上运行查询,该端点具有各种自我保护设置。这意味着昂贵的查询可能会产生部分结果或没有结果,而廉价的查询可能会产生完整的结果。您可以设置自己的镜像端点 (quick-and-easy on Amazon EC2),而无需此类保护,您应该会从等效查询中看到等效结果。

    @AKSW 对您的查询进行了调整,可以快速产生完整的结果 --

    FILTER strstarts(str(?sublcs), "http://dbpedia.org/ontology") 添加到NOT EXISTS 部分

    (参见query form 和live results)

    SELECT ?lcs
    WHERE
    
      <http://dbpedia.org/resource/Finding_Nemo>  a  ?class1  .
      ?class1  rdfs:subClassOf*  ?lcs  .
      <http://dbpedia.org/resource/Ice_Age_(2002_film)>  a  ?class2  .
      ?class2  rdfs:subClassOf*  ?lcs  .
    
      FILTER NOT EXISTS 
        <http://dbpedia.org/resource/Finding_Nemo>  a  ?class3  .
        ?class3  rdfs:subClassOf*  ?sublcs  .
        <http://dbpedia.org/resource/Ice_Age_(2002_film)>  a  ?class4  .
        ?class4  rdfs:subClassOf*  ?sublcs .
        ?sublcs  rdfs:subClassOf  ?lcs 
        FILTER strstarts( str(?sublcs), "http://dbpedia.org/ontology" )
      
    
      FILTER strstarts( str(?lcs), "http://dbpedia.org/ontology" )
    
    

(ObDisclaimer:OpenLink Software 产生 Virtuoso,它为 DBpedia 端点和 AMI referenced above 提供动力。他们也雇用了我。)

【讨论】:

是的,添加FILTER strstarts( str(?sublcs), "http://dbpedia.org/ontology" ) 有效。 我不知道有这样的设置,我认为如果查询时间太长,它会给我一个超时错误。很高兴知道。

以上是关于SPARQL 查询根据语句的顺序返回不同的结果的主要内容,如果未能解决你的问题,请参考以下文章

VB6 与 C# 以不同顺序返回的 SQL 结果集

SPARQL 联合查询不返回所有解决方案

MySQL中语句执行顺序

SPARQL 查询返回空结果集

sql in怎么根据in的顺序排列查询结果

Mybatis 查询的结果集,列的顺序如何去控制