15

我正在尝试使用 SPARQL Construct 查询从现有的命名图创建一个新的命名图。我正在查询的数据库包含http://graph.com/old一个现有的命名图。我使用Jena TDB作为数据库,通过Jena Fuseki端点访问。下面的查询给了我一个错误:

CONSTRUCT
{
    GRAPH <http://graph.com/new> {
        ?s ?p ?o
    }
}

WHERE
{
    GRAPH <http://graph.com/old> {
        ?s ?p ?o
    }
}

如果我从 CONSTRUCT 块中删除图形语句,查询将完美运行,但我想将三元组放入我指定的命名图形中,而不是默认图形。

据我所知,关于 CONSTRUCT 的 SPARQL 1.1 部分没有说明任何关于构建命名图的内容。有没有办法做到这一点?

4

2 回答 2

20

就像当您有兴趣获取一组变量绑定时使用 SELECT 查询一样,使用 CONSTRUCT 查询您有兴趣获取一个模型。就像绑定在 SELECT 结果集中的变量不会放入任何模型或持久绑定集一样,由 CONSTRUCT 构建的模型也不会存储在任何地方。您想使用 SPARQL 1.1 INSERT。更新特性在3 SPARQL 1.1 更新语言中描述。因此,您的更新请求可以写成:

INSERT {
  GRAPH <http://graph.com/new> {
    ?s ?p ?o
  }
}
WHERE {
  GRAPH <http://graph.com/old> {
    ?s ?p ?o
  }
}

但是,对于这种特殊情况,您可能可以使用3.2.3 COPY中描述的 COPY 操作。COPY 首先从目标图中删除所有数据,因此它可能不适用于您的实际情况(请理解您提供的代码可能是一个最小示例,不一定是您尝试执行的实际更新)。关于 COPY 标准说:

COPY 操作是将输入图中的所有数据插入到目标图中的快捷方式。输入图表中的数据不受影响,但目标图表中的数据(如果有)在插入之前被删除。

COPY ( SILENT )? ( ( GRAPH )? IRIref_from | DEFAULT) TO ( ( GRAPH )? IRIref_to | DEFAULT )

操作类似于:

DROP SILENT (GRAPH IRIref_to | DEFAULT);
      INSERT { ( GRAPH IRIref_to )? { ?s ?p ?o } } WHERE { ( GRAPH IRIref_from )? { ?s ?p ?o } }

COPY 和 DROP/INSERT 组合之间的区别在于,如果使用 COPY 将图形复制到自身,则不会执行任何操作,数据将保持原样。在这种情况下使用 DROP/INSERT 会导致图表为空。

如果目标图不存在,则会创建它。默认情况下,如果输入图不存在,服务可能会返回失败。如果存在 SILENT,则操作的结果将始终是成功的。

如果 COPY 不合适,那么ADD可能就是您要查找的内容:

3.2.5 添加

ADD 操作是将输入图中的所有数据插入到目标图中的快捷方式。来自输入图的数据不受影响,并且来自目标图的初始数据(如果有)保持不变。

ADD ( SILENT )? ( ( GRAPH )? IRIref_from | DEFAULT) TO ( ( GRAPH )? IRIref_to | DEFAULT)

相当于:

INSERT { ( GRAPH IRIref_to )? { ?s ?p ?o } } WHERE { ( GRAPH IRIref_from )? { ?s ?p ?o } }

如果目标图不存在,则会创建它。默认情况下,如果输入图不存在,服务可能会返回失败。如果存在 SILENT,则操作的结果将始终是成功的。

于 2013-08-21T01:26:11.637 回答
0

如果必须使用 CONSTRUCT,则必须添加三元组来标识命名图。一种方法是 rdf 物化。

CONSTRUCT {    
    ?s ?p ?o .
    ?statement 
        a rdf:Statement ;
        rdf:subject ?s ;
        rdf:predicate ?p ;
        rdf:object ?o ;
        ex:targetGraph <http://graph.com/new> ;
    .    
}
WHERE {    
    ?s ?p ?o .
    BIND(BNODE() AS ?statement)    
}

构造的三元组可以加载到另一个数据库中,并由另一个 INSERT 摄取到名为 graph 的目标中。

INSERT {
    GRAPH ?graph {
        ?s ?p ?o .
    }        
    WHERE {
    {
        SERVICE <your-triple-store-containing-the-construct> {
            ?s ?p ?o .
            ?statement
                a rdf:Statement ;
                rdf:subject ?s ;
                rdf:predicate ?p ;
                rdf:object ?o ;
                ex:targetGraph ?graph .
            .    
        }    
    }
}

你到底为什么要做这样的事情?正如我上面所说,并不总是可以直接使用 INSERT。即它在SHACL-Rules的上下文中不可用。

于 2021-10-08T09:53:07.320 回答