是否可以使用SPARQL和RDF4J批处理选择查询?

一次

我正在使用一个很大的数据集(大约500Mio-Triples)存储在graphDB Free中,并在我的本地开发人员计算机上运行。

我想对带有RDF4J的数据集进行一些操作,并且必须选择或多或少地选择整个数据集。要进行测试,我只需选择所需的元组。对于前百万个元组,该代码运行良好,此后,由于graphDB继续分配更多的RAM,它变得非常慢。

是否可以对非常大的数据集进行SELECT查询并批量获取它们?

基本上,我只想“迭代”某些选定的三元组,因此不必使用来自graphDB的那么多RAM。我可以看到我已经准备好在查询完成之前在RDF4J中获取数据,因为它仅在大约1.4 Mio读取元组时崩溃(HeapSpaceError)。不幸的是,graphDB不能以某种方式释放所有就绪读取元组的内存。我想念什么吗?

非常感谢你的帮助。

ps。我已经将graphDB的可用heapSpace设置为20GB。

RDF4J(Java)代码如下所示:

package ch.test;


import org.eclipse.rdf4j.query.*;
import org.eclipse.rdf4j.repository.RepositoryConnection;
import org.eclipse.rdf4j.repository.http.HTTPRepository;

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;

public class RDF2RDF {

    public static void main(String[] args) {
        System.out.println("Running RDF2RDF");

        HTTPRepository sourceRepo = new HTTPRepository("http://localhost:7200/repositories/datatraining");
        try {
            String path = new File("").getAbsolutePath();
            String sparqlCommand= Files.readString(Paths.get(path + "/src/main/resources/sparql/select.sparql"), StandardCharsets.ISO_8859_1);

            int chunkSize = 10000;
            int positionInChunk = 0;
            long loadedTuples = 0;

            RepositoryConnection sourceConnection = sourceRepo.getConnection();
            TupleQuery query = sourceConnection.prepareTupleQuery(sparqlCommand);

            try (TupleQueryResult result = query.evaluate()) {
                for (BindingSet solution:result) {
                    loadedTuples++;
                    positionInChunk++;

                    if (positionInChunk >= chunkSize) {
                        System.out.println("Got " + loadedTuples + " Tuples");
                        positionInChunk = 0;
                    }
                }
            }

        } catch (IOException err) {
            err.printStackTrace();
        }
    }
}

select.sparql:

PREFIX XXX_meta_schema: <http://schema.XXX.ch/meta/>
PREFIX XXX_post_schema: <http://schema.XXX.ch/post/>
PREFIX XXX_post_tech_schema: <http://schema.XXX.ch/post/tech/>

PREFIX XXX_geo_schema: <http://schema.XXX.ch/geo/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX XXX_raw_schema: <http://schema.XXX.ch/raw/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

SELECT * WHERE {

    BIND(<http://data.XXX.ch/raw/Table/XXX.csv> as ?table).

    ?row XXX_raw_schema:isDefinedBy ?table.

    ?cellStreetAdress XXX_raw_schema:isDefinedBy ?row;
        XXX_raw_schema:ofColumn <http://data.XXX.ch/raw/Column/Objektadresse>;
        rdf:value ?valueStreetAdress.

    ?cellOrt mobi_raw_schema:isDefinedBy ?row;
        XXX_raw_schema:ofColumn <http://XXX.mobi.ch/raw/Column/Ort>;
        rdf:value ?valueOrt.

    ?cellPlz mobi_raw_schema:isDefinedBy ?row;
        XXX_raw_schema:ofColumn <http://XXX.mobi.ch/raw/Column/PLZ>;
        rdf:value ?valuePLZ.

    BIND (URI(concat("http://data.XXX.ch/post/tech/Adress/", MD5(STR(?cellStreetAdress)))) as ?iri_tech_Adress).
}

我的解决方案:使用子选择statemant首先获取所有“行”。

PREFIX mobi_post_schema: <http://schema.mobi.ch/post/>
PREFIX mobi_post_tech_schema: <http://schema.mobi.ch/post/tech/>

PREFIX mobi_geo_schema: <http://schema.mobi.ch/geo/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX mobi_raw_schema: <http://schema.mobi.ch/raw/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

SELECT * WHERE {

    {
        SELECT ?row WHERE
        {
            BIND(<http://data.mobi.ch/raw/Table/Gebaeudeobjekte_August2020_ARA_Post.csv> as ?table).

            ?row mobi_raw_schema:isDefinedBy ?table.
        }
    }


    ?cellStreetAdress mobi_raw_schema:isDefinedBy ?row;
        mobi_raw_schema:ofColumn <http://data.mobi.ch/raw/Column/Objektadresse>;
        rdf:value ?valueStreetAdress.

    ?cellOrt mobi_raw_schema:isDefinedBy ?row;
        mobi_raw_schema:ofColumn <http://data.mobi.ch/raw/Column/Ort>;
        rdf:value ?valueOrt.

    ?cellPlz mobi_raw_schema:isDefinedBy ?row;
        mobi_raw_schema:ofColumn <http://data.mobi.ch/raw/Column/PLZ>;
        rdf:value ?valuePLZ.

    BIND (URI(concat("http://data.mobi.ch/post/tech/Adress/", MD5(STR(?cellStreetAdress)))) as ?iri_tech_Adress).
}
简·布罗克斯特拉

我不立即知道为什么给出的查询对于GraphDB Free而言如此昂贵,在内存方面如此昂贵,但是通常在很大程度上取决于数据集的形状和大小。当然,首先进行基本检索整个数据库的查询不一定是明智的选择。

话虽这么说,您可以尝试以下两种方法。使用分页机制LIMITOFFSET作为分页机制是一种方法。

您可以尝试的另一种选择是将查询分为两部分:一个查询将检索您感兴趣的资源的所有标识符,然后对它们进行迭代,然后对每个标识符进行单独的查询以获取该资源的详细信息(属性和关系)特定资源。

在您的示例中,您可以在上分割?row,因此您首先要进行查询以获取给定表的所有行:

SELECT ?row WHERE {
    VALUES ?table { <http://data.XXX.ch/raw/Table/XXX.csv> }
    ?row XXX_raw_schema:isDefinedBy ?table.
}

然后,您遍历该结果,将每个返回的值注入?row到检索详细信息的查询中:

SELECT * WHERE {
    VALUES ?row { <http://data.XXX.ch/raw/Table/XXX.csv#row1> }

    ?cellStreetAdress XXX_raw_schema:isDefinedBy ?row;
        XXX_raw_schema:ofColumn <http://data.XXX.ch/raw/Column/Objektadresse>;
        rdf:value ?valueStreetAdress.

    ?cellOrt mobi_raw_schema:isDefinedBy ?row;
        XXX_raw_schema:ofColumn <http://XXX.mobi.ch/raw/Column/Ort>;
        rdf:value ?valueOrt.

    ?cellPlz mobi_raw_schema:isDefinedBy ?row;
        XXX_raw_schema:ofColumn <http://XXX.mobi.ch/raw/Column/PLZ>;
        rdf:value ?valuePLZ.

    BIND (URI(concat("http://data.XXX.ch/post/tech/Adress/", MD5(STR(?cellStreetAdress)))) as ?iri_tech_Adress).
}

在Java代码中,如下所示:


String sparqlCommand1 = // the query for all rows of the table

// query for details of each row. Value of row will be injected via the API
String sparqlCommand2 = "SELECT * WHERE { \n"
                    + "    ?cellStreetAdress XXX_raw_schema:isDefinedBy ?row;\n"
                    + "        XXX_raw_schema:ofColumn <http://data.XXX.ch/raw/Column/Objektadresse>;\n"
                    + "        rdf:value ?valueStreetAdress.\n"
                    + "    ?cellOrt mobi_raw_schema:isDefinedBy ?row;\n"
                    + "        XXX_raw_schema:ofColumn <http://XXX.mobi.ch/raw/Column/Ort>;\n"
                    + "        rdf:value ?valueOrt.\n"
                    + "    ?cellPlz mobi_raw_schema:isDefinedBy ?row;\n"
                    + "        XXX_raw_schema:ofColumn <http://XXX.mobi.ch/raw/Column/PLZ>;\n"
                    + "        rdf:value ?valuePLZ.\n"
                    + "    BIND (URI(concat(\"http://data.XXX.ch/post/tech/Adress/\", MD5(STR(?cellStreetAdress)))) as ?iri_tech_Adress).\n"
                    + "}";

try(RepositoryConnection sourceConnection = sourceRepo.getConnection()) {
     TupleQuery rowQuery = sourceConnection.prepareTupleQuery(sparqlCommand1);     
     TupleQuery detailsQuery = sourceConnection.prepareTupleQuery(sparqlCommand2);

     try (TupleQueryResult result = rowQuery.evaluate()) {
         for (BindingSet solution: result) {
                // inject the current row identifier
                detailsQuery.setBinding("row", solution.getValue("row"));

                // execute the details query for the row and do something with 
                // the result
                detailsQuery.evaluate().forEach(System.out::println);
         }
     }
}

您当然会以这种方式进行更多查询(N + 1,其中N是行数),但是每个查询结果只是一小块,对于GraphDB Free(以及您自己的应用程序)来说,可能更易于管理。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

RDF4J SPARQL查询到JSON

来自分类Dev

使用RDF4J SPARQLRepository查询Marklogic

来自分类Dev

rdf4j构造查询失败

来自分类Dev

http 上的 rdf4j lucene

来自分类Dev

在SPARQL查询中选择主题和rdf:type

来自分类Dev

是否可以使用GraphRepository模式动态构造neo4j密码查询

来自分类Dev

RDF4J 仅针对 Triple Store 调度 5 个查询

来自分类Dev

使用 SPARQL 和 SPIN 对数据进行 RDF 处理

来自分类Dev

使用 RDF4J 在远程服务器上创建存储库

来自分类Dev

是否可以使用neo4j的默认图形?

来自分类Dev

是否可以使用OFFSET和乘法来分页查询?

来自分类Dev

是否可以使用批处理脚本编写 FFmpeg 脚本以并行编码多个文件?

来自分类Dev

GraphDB或RDF4J错误?BOUND()产生错误的值

来自分类Dev

通过 RDF4J API 配置/启用 GeoSPARQL 插件

来自分类Dev

使用 SPARQL 查询 Jena 创建的 RDF 属性

来自分类Dev

是否可以重写NOT IN查询以使用索引?

来自分类Dev

是否可以使用DOMDocument查询nthChild?

来自分类Dev

是否可以使用mysql代理在Microsoft sql服务器之前进行查询处理?

来自分类Dev

是否可以使用批处理文件ping多个IP地址,每个IP地址都在其自己的窗口中?

来自分类Dev

是否可以使用Java API确定“节点”是否在Neo4J中的事务中?

来自分类Dev

是否可以使用查询select及其索引来选择数组中的元素?

来自分类Dev

SPARQL查询RDF本体

来自分类Dev

RDF4J REST API 更新返回 500,“事务处理错误:java.util.concurrent.ExecutionException:java.lang.NullPointerException”

来自分类Dev

是否可以在SPARQL查询中使用嵌套删除?

来自分类Dev

是否可以在SPARQL查询中使用嵌套删除?

来自分类Dev

是否可以使用for循环和mutate()?

来自分类Dev

我们是否可以使用条件查询来查找记录的一个选择查询的结果

来自分类Dev

可以描述SPARQL查询的RDF名称空间吗?

来自分类Dev

是否可以使用Fortran的选择类型来识别和区分类型?

Related 相关文章

  1. 1

    RDF4J SPARQL查询到JSON

  2. 2

    使用RDF4J SPARQLRepository查询Marklogic

  3. 3

    rdf4j构造查询失败

  4. 4

    http 上的 rdf4j lucene

  5. 5

    在SPARQL查询中选择主题和rdf:type

  6. 6

    是否可以使用GraphRepository模式动态构造neo4j密码查询

  7. 7

    RDF4J 仅针对 Triple Store 调度 5 个查询

  8. 8

    使用 SPARQL 和 SPIN 对数据进行 RDF 处理

  9. 9

    使用 RDF4J 在远程服务器上创建存储库

  10. 10

    是否可以使用neo4j的默认图形?

  11. 11

    是否可以使用OFFSET和乘法来分页查询?

  12. 12

    是否可以使用批处理脚本编写 FFmpeg 脚本以并行编码多个文件?

  13. 13

    GraphDB或RDF4J错误?BOUND()产生错误的值

  14. 14

    通过 RDF4J API 配置/启用 GeoSPARQL 插件

  15. 15

    使用 SPARQL 查询 Jena 创建的 RDF 属性

  16. 16

    是否可以重写NOT IN查询以使用索引?

  17. 17

    是否可以使用DOMDocument查询nthChild?

  18. 18

    是否可以使用mysql代理在Microsoft sql服务器之前进行查询处理?

  19. 19

    是否可以使用批处理文件ping多个IP地址,每个IP地址都在其自己的窗口中?

  20. 20

    是否可以使用Java API确定“节点”是否在Neo4J中的事务中?

  21. 21

    是否可以使用查询select及其索引来选择数组中的元素?

  22. 22

    SPARQL查询RDF本体

  23. 23

    RDF4J REST API 更新返回 500,“事务处理错误:java.util.concurrent.ExecutionException:java.lang.NullPointerException”

  24. 24

    是否可以在SPARQL查询中使用嵌套删除?

  25. 25

    是否可以在SPARQL查询中使用嵌套删除?

  26. 26

    是否可以使用for循环和mutate()?

  27. 27

    我们是否可以使用条件查询来查找记录的一个选择查询的结果

  28. 28

    可以描述SPARQL查询的RDF名称空间吗?

  29. 29

    是否可以使用Fortran的选择类型来识别和区分类型?

热门标签

归档