【问题标题】:Alternative for OPTIONAL Keyword in SPARQL-Queries?SPARQL 查询中可选关键字的替代方案?
【发布时间】:2014-10-25 21:50:32
【问题描述】:

我有一个 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 端点(Virtuoso 服务器)运行此查询时,我收到了错误:

Virtuoso 42000 错误估计执行时间-721420288(秒) 超过 400(秒)的限制。

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

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

【问题讨论】:

    标签: rdf sparql virtuoso


    【解决方案1】:

    对于 SPARQL 引擎,OPTIONAL 模式的评估成本通常很高(与“正常”连接模式相比)。在这种情况下,错误表明 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,则使用芝麻模型或内存存储库),然后从那里进一步查询。

    【讨论】:

    • 我真正喜欢的一件事(但不知道它会有多贵)是能够做类似from [construct { ... } where { ... }] select ... where { ... } 的事情。这将使一些困难的任务变得非常容易。
    • @JoshuaTaylor 它总是让我觉得奇怪的是CONSTRUCT(在某种程度上,它是 RDF 的更“自然”的查询类型)不容易与其他的组合/链接查询。我们有子选择 - 为什么没有子结构?我认为这是 WG 刚刚提出的“可能很好,但现在不行”的功能之一。
    • 是的,将来会很好,我们实际上在 YarcData 内部实现了 CONSTRUCT 子查询,尽管不在 FROM 子句中。我们将它们用作调用更传统的图形分析(例如 k-means、最短路径等)的一种方式,将它们用作应用自定义修饰符的子查询,以便可以合理地嵌套在常规图形模式中
    • @RobV 这听起来真的很令人兴奋。您最终是否不得不对可以构建的内容进行任何限制?实现是否在构造查询中构造查询? (一旦你有了它,你就可以implement concise bounded descriptions。)虽然子查询首先在概念上评估,是否有任何优化不首先完全评估构造,而是更多地使用它作为“另一个搜索方式”?
    • 哇,我没想到会这么难……感谢您的启发!我只是在想解决这个问题的最佳方法是什么。也许将 CONSTRUCT 子句变成 SELECT 子句,然后遍历结果集,选择所需的属性?这样的解决方案有任何倒退吗? (备案:我正在使用 RobVs dotNetRdf)
    猜你喜欢
    • 2013-02-08
    • 1970-01-01
    • 2017-11-06
    • 2018-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多