GRAPH — query named graphs
Every triple in pgRDF lives in a graph (see Managing graphs). A pattern without GRAPH matches across all of them, including the default graph. GRAPH narrows it down.
| Form | Matches |
|---|---|
GRAPH <iri> { … } | Only the graph with that IRI. An IRI that names no graph matches nothing. |
GRAPH ?g { … } | Each named graph in turn, with ?g bound to its IRI. The default graph is not included. |
No GRAPH | All graphs, including the default graph. |
The default graph's IRI is urn:pgrdf:graph:0, so GRAPH <urn:pgrdf:graph:0> { … } reads only the default graph.
FROM and FROM NAMED are ignored
FROM <iri> and FROM NAMED <iri> are accepted but currently have no effect: the query still runs over all graphs. Use GRAPH to choose graphs.
Example data
Two small graphs, next to the people graph from the sample data:
SELECT pgrdf.add_graph('http://example.org/g1');
SELECT pgrdf.add_graph('http://example.org/g2');
SELECT pgrdf.parse_turtle('@prefix ex: <http://example.org/> . ex:a ex:p "in g1" .',
pgrdf.graph_id('http://example.org/g1'));
SELECT pgrdf.parse_turtle('@prefix ex: <http://example.org/> . ex:a ex:p "in g2" . ex:b ex:p "only g2" .',
pgrdf.graph_id('http://example.org/g2'));Remove them afterwards with SELECT pgrdf.drop_graph('http://example.org/g1'); and the same for g2.
One graph
SELECT * FROM pgrdf.sparql($$
SELECT ?s ?o
WHERE { GRAPH <http://example.org/g1> { ?s ?p ?o } }
$$);
-- {"o": "in g1", "s": "http://example.org/a"}Which graphs match
GRAPH ?g tells you where each answer came from:
SELECT * FROM pgrdf.sparql($$
PREFIX ex: <http://example.org/>
SELECT ?g ?o WHERE { GRAPH ?g { ex:a ex:p ?o } }
ORDER BY ?g
$$);
-- {"g": "http://example.org/g1", "o": "in g1"}
-- {"g": "http://example.org/g2", "o": "in g2"}Combined with an aggregate, it counts triples per graph:
SELECT * FROM pgrdf.sparql($$
SELECT ?g (COUNT(*) AS ?n)
WHERE { GRAPH ?g { ?s ?p ?o } }
GROUP BY ?g ORDER BY ?g
$$);
-- {"g": "http://example.org/g1", "n": "1"}
-- {"g": "http://example.org/g2", "n": "2"}
-- {"g": "http://example.org/people", "n": "14"}Combining with OPTIONAL, UNION and MINUS
OPTIONAL inside GRAPH
SELECT * FROM pgrdf.sparql($$
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?g ?name ?mbox
WHERE { GRAPH ?g { ?s foaf:name ?name
OPTIONAL { ?s foaf:mbox ?mbox } } }
ORDER BY ?name
$$);
-- {"g": "http://example.org/people", "mbox": "mailto:alice@example.org", "name": "Alice"}
-- {"g": "http://example.org/people", "mbox": null, "name": "Bob"}
-- {"g": "http://example.org/people", "mbox": "mailto:carol@example.org", "name": "Carol"}UNION across two graphs
SELECT * FROM pgrdf.sparql($$
PREFIX ex: <http://example.org/>
SELECT ?s ?o
WHERE { { GRAPH <http://example.org/g1> { ?s ex:p ?o } }
UNION
{ GRAPH <http://example.org/g2> { ?s ex:p ?o } } }
ORDER BY ?o
$$);
-- {"o": "in g1", "s": "http://example.org/a"}
-- {"o": "in g2", "s": "http://example.org/a"}
-- {"o": "only g2", "s": "http://example.org/b"}MINUS to subtract one graph from another
Subjects in g2 that g1 doesn't mention, the way you'd compare a graph with an earlier snapshot:
SELECT * FROM pgrdf.sparql($$
PREFIX ex: <http://example.org/>
SELECT ?s
WHERE { GRAPH <http://example.org/g2> { ?s ex:p ?o }
MINUS { GRAPH <http://example.org/g1> { ?s ex:p ?o2 } } }
$$);
-- {"s": "http://example.org/b"}Choosing graphs by list
VALUES ?g { … } and FILTER(?g = …) on the variable of GRAPH ?g are refused with an error. Either name each graph in a UNION (as in UNION across two graphs), or query all graphs with GRAPH ?g and keep the ones you want in SQL:
SELECT sparql
FROM pgrdf.sparql($$
PREFIX ex: <http://example.org/>
SELECT ?g ?o WHERE { GRAPH ?g { ex:a ex:p ?o } }
$$)
WHERE sparql->>'g' IN ('http://example.org/g1', 'http://example.org/g2')
ORDER BY 1;
-- {"g": "http://example.org/g1", "o": "in g1"}
-- {"g": "http://example.org/g2", "o": "in g2"}In updates
GRAPH <iri> { … } works in the templates and patterns of SPARQL UPDATE too, and WITH <iri> scopes a whole update to one graph. Check which graph an update writes to before running one.
See also
- Managing graphs: create, inspect, copy, lock and drop graphs.
- Named graphs: how graph IRIs map to ids.