【问题标题】:SPARQL : OFFSET whithout ORDER BY to get all results of a query?SPARQL:OFFSET 没有 ORDER BY 来获取查询的所有结果?
【发布时间】:2018-01-29 11:39:36
【问题描述】:

我有一个大型 TDB 数据集(参见这篇文章 Fuseki config for 2 datasets + text index : how to use turtle files?),我需要提取数据以制作“子图”并将其导入 fuseki。 我发现OFFSET 可能是一个解决方案,如果这些结果太多(大约 12M 三元组),则可以获取所有查询结果。

这是我的问题

1) 我读到 W3C 建议 OFFSET 应该与 ORDER BY 一起使用:

使用 LIMIT 和 OFFSET (...) 不会有用 除非订单是 使用 ORDER BY 使其可预测

(参见https://www.w3.org/TR/rdf-sparql-query/#modOffset

-- 不幸的是,ORDER BY 在我的数据集上似乎很长。我发现了一些没有 ORDER BY 的 OFFSET 示例(这里有一个:Getting list of persons using SPARQL dbpedia),所以我尝试单独使用OFFSET,它似乎有效。

-- 我需要确保如果我重复相同的查询,我会得到所有结果。因此,我尝试了一个样本,并检查了结果是否给出了不同的值和预期的数字,一切似乎都很好。 所以我假设只有在 2 个查询(“可预测的顺序”)之间修改数据集时才需要 ORDER BY?

2) 性能是否取决于比率限制/偏移?

-- 我用相同的偏移量尝试了 LIMIT = 100, 1000, 5000, 10000,速度似乎差不多。

-- 还尝试比较不同的OFFSET值,似乎大偏移量的执行时间更长(但也许这只是TDB的问题:cf:https://www.mail-archive.com/users@jena.apache.org/msg13806.html

~~~~~~ 更多信息 ~~~~~~

-- 我使用带有tdbquery 的脚本和这个命令:

./tdbquery --loc=$DATASET --time --results=ttl "$PREFIXES construct { ?exp dcterms:title ?titre } where { ?manif dcterms:title ?titre ; rdarelationships:expressionManifested ?exp } limit $LIMIT offset $OFFSET"

-- 数据集:~168M 三元组和 ~12M 三元组与 dcterms:title 。

~~~~~~~~~~~~~~~~~~~~~~~~~

提前致谢

【问题讨论】:

  • 1) 是正确的,不能保证如果没有 ORDER BY,您将以相同的顺序遍历数据,一切都将依赖于三重存储。它可能有效,但形式上你不能保证它。
  • 2) 较大的 OFFSET 可能会很昂贵,因为您必须扫描评估查询的较大结果。它不依赖于 TDB,其他三重存储也表现不佳,尽管可能存在具有不同行为的三重存储
  • 如果你有自己的Fuseki,为什么需要OFFSET来获取所有数据?这仅对带有一些选项以限制每个查询返回的结果的三重存储是必需的。例如,DBpedia 部署在 Virtuoso 上,由于公共端点是共享服务,因此限制为 10000。显然,如果您使用自己的服务器,则可以在 virtuoso.ini 中进行配置。
  • 非常感谢。关于 1),您说“一切都取决于三重商店”。我尝试了 500 000 个三元组的样本,似乎没问题:你知道 TDB 是否可以这样使用?
  • SELECT 的查询执行几乎总是流式传输。 ORDER BY 阻止了这一点。 DISTINCT 正在流式传输,但会消耗工作空间 (RAM)。但 CONSTRUCT 不是流式传输 - 它需要构建模型。所以执行一个 SELECT 查询“SELECT REDUCE ?exp ?titre”并在本地构建三元组。 REDUCE 是便宜的 DISTINCT 并且占用的空间很小。在创建模型时,重复是无关紧要的。

标签: sparql jena tdb


【解决方案1】:

感谢 AKSW 和 Andy,你们的 cmets 帮助我了解了 Sparql。

所以我尝试使用SELECT REDUCED,但是它很长,如果我不使用OFFSET,则无法停止该过程。此外,我需要转换结果以生成新图(我想对作者进行其他转换等)。

我阅读了一些关于流、模型和序列化的页面,发现我可以在同一个查询中通过多次更新直接转换数据。这是一个潜在的解决方案:首先制作 TDB 文件的副本,然后在 while 循环中使用此查询:

DELETE {
    ?manif dcterms:title ?titre ;
        rdarelationships:expressionManifested ?exp   
}
INSERT { 
    graph <http://titres_1> { 
        ?manif rdarelationships:expressionManifested ?exp .
        ?exp dcterms:titre ?titre 
    }
} 
WHERE {  
    select * where 
        { 
            ?manif dcterms:title ?titre ;
                rdarelationships:expressionManifested ?exp 
        }
    LIMIT 100000 
}

这个解决方案有几个优点:

  • 很简单,没有java代码(我不懂Jena类也不懂Java,现在没时间学习)也没有文件处理。
  • 我可以在需要时停止该进程。
  • 每次删除结果可以确保检索到所有匹配的三元组
  • 每次删除后,默认图都会变小,因此查询应该越来越高效

也许可以做一些更有效的事情:任何想法都会受到赞赏。

----- 编辑 ----------

我已经开始转换数据,使用 bash 脚本重复查询,s-get ... | split 将三元组导出到 .nt 文件中。每次导出后,都会使用 s-update 清除“temp”图。

一切似乎都还好,但是

  1. 花费的时间比我想象的要多(对于 50 x 限制 = 10 000 的查询,大约需要 1 小时)。
  2. 我的 TDB 文件现在比我想象的要大得多。好像删除的三元组并没有真正删除(它们是否存储在一些“备份”图中?或者可能只有索引被修改?)。转换前:默认图中有 168 300 000 个三元组,TDB 文件有 20,6 个 Go。现在:~ 155 100 000 在默认图中,55 Go for files...

因此,有两个问题:

  • a) 这是“正常”行为吗?我可以减小文件大小(不仅仅是存储问题,我认为下一次查询应该更快)?
  • b) 您是否知道另一种方法,使用命令行实用程序会更快?

提前致谢


最后编辑

文件大小和性能似乎取决于可以在tdb.cfg 文件中设置的参数:请参阅http://jena.apache.org/documentation/tdb/store-parameters.html

我的数据集文件夹中没有任何 .cfg 文件。我做的第一个测试是添加一个并将 tdb.file_mode 更改为 'direct' :文件的大小似乎没有像以前那样增长。但是,它需要更多的 RAM,并且查询速度较低(即使我增加了 java -Xms 和 -Xmx)。我认为文件大小和查询性能之间存在“权衡”。如果我有时间,我会订阅 jena-users 邮件列表,询问什么是最好的“调整”。

结论:测试查询很有趣,但是我的数据集太大了;我将使用命名图(但使用 tdbloader2 不允许这样做)或几个较小的数据集从原始 xml 文件中制作另一个。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-19
    • 1970-01-01
    相关资源
    最近更新 更多