Reputation: 3096
I'm looking for an easy way to insert triples from two or more named graphs (but not the entire unnamed default graph) into another named graph. I'm using GraphDB.
I guess this could be done by writing out the same query multiple times in the WHERE
section, wrapped in multiple GRAPH
specifications, and then unioning them together, but my WHERE
s are long and I'd prefer not to write them out multiple times.
Let's say I have loaded some data like this:
INSERT DATA {
GRAPH <http://example.com/ngA> {
<http://example.com/person1> <http://example.com/name> "Arthur" .
}
GRAPH <http://example.com/ngB> {
<http://example.com/person1> <http://example.com/name> "Brian" .
}
GRAPH <http://example.com/ngC> {
<http://example.com/person1> <http://example.com/name> "Charlie" .
}
}
I can copy all of the triples of a certain pattern from the default unnamed graph into a new named graph with something like this:
INSERT {
GRAPH <http://example.com/ngZ> {
?s <http://example.com/moniker> ?o .
}
}
WHERE
{ ?s <http://example.com/name> ?o }
An easy way to SELECT
for triples of a given pattern from two or more (but not all) named graphs is
SELECT *
FROM <http://example.com/ngA>
FROM <http://example.com/ngB>
WHERE
{ ?s <http://example.com/name> ?o }
What if I want to copy those triples, from those specified graphs, into another graph?
I'm getting an error from GraphDB 8.3 (and from the sparql.org validator) when I try to
INSERT {
GRAPH <http://example.com/ngZ> {
?s <http://example.com/moniker> ?o .
}
}
WHERE
{ SELECT *
FROM <http://example.com/ngA>
FROM <http://example.com/ngB>
WHERE
{ ?s <http://example.com/name> ?o } }
Upvotes: 6
Views: 1318
Reputation: 1697
SPARQL Update provides USING
and USING NAMED
analogous to FROM
and FROM NAMED
in queries:
The USING and USING NAMED clauses affect the RDF Dataset used while evaluating the WHERE clause. This describes a dataset in the same way as FROM and FROM NAMED clauses
You can express the requirement as an UPDATE like so:
INSERT {
GRAPH <http://example.com/ngZ> {
?s <http://example.com/moniker> ?o .
}
}
USING <http://example.com/ngA>
USING <http://example.com/ngB>
WHERE
{ ?s <http://example.com/name> ?o }
Also note that, according to the SPARQL query grammar, a subquery does not admit a dataset clause. This is why the SPARQL parsers are rejecting your query.
Upvotes: 5
Reputation: 3096
Thanks, @Stanislav Kralin
Come to think of it, this also works:
PREFIX ex: <http://example.com/>
INSERT {
GRAPH ex:ngZ {
?s ex:moniker ?o
}
}
WHERE {
values ?g {
ex:ngA ex:ngB
}
GRAPH ?g {
?s ex:name ?o
}
}
Upvotes: 3
Reputation: 11459
Try this query:
PREFIX ex: <http://example.com/>
INSERT {
GRAPH ex:ngZ { ?s ex:moniker ?o }
}
WHERE {
GRAPH ?g { ?s ex:name ?o }
FILTER (?g IN ( ex:ngA, ex:ngB ) )
}
And then:
PREFIX ex: <http://example.com/>
SELECT *
FROM NAMED ex:ngZ
WHERE {
GRAPH ?g { ?s ?p ?o }
} LIMIT 100
Is it what you need?
By the way, there exist COPY
(use with caution!) and ADD
.
Upvotes: 6