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 Nemo 的rdf:type
s 的数量(~55)超过了 Ice 的rdf:type
s 的数量年龄 (~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 查询根据语句的顺序返回不同的结果的主要内容,如果未能解决你的问题,请参考以下文章