run a sparql query against two graphs?

Joe Corneli picture Joe Corneli · Mar 10, 2013 · Viewed 10k times · Source

A typical SPARQL query that specifies a graph might look like this:

SELECT ?b ?c WHERE { GRAPH <http://AliceIRI> {
<http://local.virt/foo> ?b ?c}}

This will tell me all the triples in AliceIRI where "foo" is a subject. What if I want to look in two different graphs, is my only option to do a UNION:

SELECT ?b ?c WHERE {{ GRAPH <http://AliceIRI> {
<http://local.virt/foo> ?b ?c}}
UNION
{ GRAPH <http://BobIRI> {
<http://local.virt/foo> ?b ?c}}}

Or is there some shorthand that would allow me to write this more conveniently, something like this:

SELECT ?b ?c WHERE { GRAPH <http://AliceIRI> + <http://BobIRI> {
<http://local.virt/foo> ?b ?c}

BTW I'm on Virtuoso 6.01.3127.

Update 1

To clarify, I'd really like to be able to run:

SELECT ?b ?c WHERE { GRAPH <http://AliceIRI> + <http://BobIRI> {
<http://local.virt/foo> ?b ?c .
<http://local.virt/bar> ?b ?c}}

and have this match ?b and ?c such that <http://local.virt/foo> ?b ?c is in <http://AliceIRI> and <http://local.virt/bar> ?b ?c is in <http://BobIRI>. Simply taking the union of matches in <http://AliceIRI> (alone) and <http://BobIRI> (alone) won't accomplish this.

And to clarify further: I've realized that if the foos all belonged to Alice and the bars all belonged to Bob, then I could write

SELECT ?b ?c WHERE { 
GRAPH <http://AliceIRI> {
<http://local.virt/foo> ?b ?c } .
GRAPH <http://BobIRI> {
<http://local.virt/bar> ?b ?c}}

(which is actually what I needed for my application) -- but at least for "academic interest" the question of whether there is a syntactically nice way to run a query against a union of graphs (as opposed to against multiple graphs and then union the results) still stands.

Answer

RobV picture RobV · Mar 11, 2013

Yes

SELECT ?b ?c
FROM NAMED <http://AliceIRI>
FROM NAMED <http://BobIri>
WHERE
{
  GRAPH ?g { <http://local.virt/foo> ?b ?c }
}

FROM NAMED clauses may be used to set named graphs that are queried when you use a GRAPH ?var clause.

It is important to note that semantically this query is identical to what you wrote above so the pattern expressed by the GRAPH clause is matched against each named graph separately and unioned together

Edit

To answer the extra question in your comment yes you can, if you use FROM instead of FROM NAMED this sets the default graph for the query to be the merge of all graphs in FROM clauses and does not require you to use GRAPH e.g.

SELECT ?b ?c
FROM <http://AliceIRI>
FROM <http://BobIri>
WHERE
{
  <http://local.virt/foo> ?b ?c
}

This covers the case where you want to allow triples that match different parts of the triple pattern come from any of the graphs you have named.

Note that some triple stores may allow you to set them up so that the default graph is automatically treated as the merge of all named graphs.