将CONSTRUCT转换为一个命名图形

15

我试图使用SPARQL构造查询从一个现有的命名图创建一个新的命名图。我所查询的数据库包含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块中删除图形语句,查询将完美地工作,但我希望将三元组放入我指定的命名图而不是默认的。据我所知,SPARQL 1.1关于CONSTRUCT的章节没有提到构建命名图。有没有一种方法可以做到这一点?

2个回答

20

与SELECT查询用于获取一组变量绑定相似,CONSTRUCT查询用于获取模型。与在SELECT结果集中绑定的变量不会放入任何模型或持久绑定集合中一样,由CONSTRUCT构建的模型也不会存储在任何地方。您需要使用SPARQL 1.1 INSERT。更新功能在3 SPARQL 1.1 Update Language中描述。因此,您的更新请求可以编写为:

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,标准规定如下:

The COPY operation is a shortcut for inserting all data from an input graph into a destination graph. Data from the input graph is not affected, but data from the destination graph, if any, is removed before insertion.

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

is similar in operation to:

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

The difference between COPY and the DROP/INSERT combination is that if COPY is used to copy a graph onto itself then no operation will be performed and the data will be left as it was. Using DROP/INSERT in this situation would result in an empty graph.

If the destination graph does not exist, it will be created. By default, the service may return failure if the input graph does not exist. If SILENT is present, the result of the operation will always be success.

如果COPY不适合,那么ADD可能是您正在寻找的内容:

3.2.5 ADD

The ADD operation is a shortcut for inserting all data from an input graph into a destination graph. Data from the input graph is not affected, and initial data from the destination graph, if any, is kept intact.

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

is equivalent to:

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

If the destination graph does not exist, it will be created. By default, the service may return failure if the input graph does not exist. If SILENT is present, the result of the operation will always be success.


2
COPY 的替代方案当然是 ADD,这会将源数据复制到目标位置并保留目标图形的现有数据。 - RobV
@RobV 很好的观点!我没有做过太多的SPARQL 1.1更新,我想我在找到COPY后没有读到规范的更深层次。我会添加ADD。 - Joshua Taylor

0
如果您必须使用CONSTRUCT,那么您需要添加三元组来标识命名图。一种方法是使用RDF重ification。
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摄入到目标命名图中。

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的上下文中是不可用的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接