rdf - SPARQL 查询中 OPTIONAL 关键字的替代方法?

标签 rdf sparql virtuoso

我有一个 sparql-Query,它询问给定类型的 URI 的某些属性。由于我不确定这些属性是否存在,我使用 OPTIONAL 关键字:

PREFIX mbo: <http://creativeartefact.org/ontology/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> 
SELECT * WHERE {
  ?uri a mbo:LiveMusicEvent. 
    OPTIONAL {?uri rdfs:label ?label}. 
    OPTIONAL {?uri mbo:organisedBy ?organiser}. 
    OPTIONAL {?uri mbo:takesPlaceAt ?venue}. 
    OPTIONAL {?uri mbo:begin ?begin}. 
    OPTIONAL {?uri mbo:end ?end}. 
}

当我对 SPARQL-Endpoint(Virtuoso 服务器)运行此查询时,出现错误:

Virtuoso 42000 Error The estimated execution time -721420288 (sec) exceeds the limit of 400 (sec).



当我减少 OPTIONAL 子句时,在第一个删除的子句之后,估计执行时间为 4106 秒,当我删除两个子句时,执行查询(并立即返回值)。

我不明白,为什么使用附加的 OPTIONAL 子句估计执行时间会像这样飙升,但也许我只是使用了错误的构造查询?

最佳答案

OPTIONAL 模式对于 SPARQL 引擎的评估(与“正常”连接模式相比)通常很昂贵。在这种情况下,错误表明 Virtuoso 的查询规划器估计查询过于复杂,无法在设定的时间限制内执行(请注意,它对此进行了估计 - 因此精确值可能是错误的)。

您有多种选择。不过,它们中的大多数都涉及执行多个查询。一个常见的模式是“检索和迭代”模式——首先进行一个查询,检索 mbo:LiveMusicEvent 的所有实例。 :

 SELECT ?uri WHERE { ?uri a mbo:LiveMusicEvent } 

然后迭代结果并检索每个实例的可选属性:
SELECT * 
WHERE { VALUES(?uri) { <http://example.org/instance1> } 
        OPTIONAL {?uri rdfs:label ?label}. 
        OPTIONAL {?uri mbo:organisedBy ?organiser}. 
        OPTIONAL {?uri mbo:takesPlaceAt ?venue}. 
        OPTIONAL {?uri mbo:begin ?begin}. 
        OPTIONAL {?uri mbo:end ?end}. 
}

如您所见,我使用了 VALUES clause将第一个查询的实例 ID 结果插入到第二个查询中。在这个例子中,我假设你一个一个地迭代,因此对每个实例进行查询,但作为进一步的优化,你可能会修改将多个实例添加到 VALUES 中。一次性子句(显然不是所有的都一次,因为这会使查询与原始查询具有相同的复杂性)。

顺便说一句,VALUES是 SPARQL 1.1 功能,我不确定 Virtuoso 是否支持它。如果没有,您可以通过使用 FILTER 来达到相同的效果。子句或仅“手动”替换所有出现的变量 ?uri带有每次迭代的实例 ID。

处理它的另一种方法是首先执行一个 CONSTRUCT 查询,从更大的源中检索相关的数据子集,然后使用该子集的可选项执行更复杂的查询。例如:
 CONSTRUCT 
 WHERE { 
    ?uri a mbo:LiveMusicEvent; 
         ?p ?o . 
 }

将检索有关 LiveMusicEvent 的所有数据实例作为 RDF 图。将该图放入本地 RDF 模型(例如,如果您使用 Java,则为 Sesame 模型或内存存储库),并从那里进一步查询。

关于rdf - SPARQL 查询中 OPTIONAL 关键字的替代方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25609691/

相关文章:

使用 Jena 的 RDF/XML

rdf - 单个请求中的多个 SPARQL "INSERT WHERE"查询

java - 从 SPARQL 更新查询获取受影响的三元组

performance - Neo4j和OpenLink Virtuoso

sparql - Virtuoso SRARQL 结果中的 double 值被截断(四舍五入)

rdf - 谓词中带有冒号的 SPARQL 查询

Jena 上的 OPTION(TRANSITIVE) 的 SPARQL 查询错误

rdf - SPARQL获取所有节点的所有父节点

java - SPARQL 类型转换?

cassandra - 如何在 cassandra 集群上完成 SPARQL 查询处理?