run a sparql query against two graphs?
Asked Answered
B

2

12

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.

Bicker answered 10/3, 2013 at 22:46 Comment(0)
H
13

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.

Ho answered 11/3, 2013 at 16:10 Comment(2)
If this just unions the results across graphs, rather than allowing the triple patterns to be drawn from triples in various graphs, then it is a bit of a blunt instrument. Can you clarify whether this is the only instrument available (see Update 1 above).Bicker
@JoeCorneli I have updated my answer, yes you can do this with a slightly different queryHo
T
3

If you have to run a query in a subset of the graphs that you are using you can also set a filter on the iri of the graphs.

eg:

SELECT ?b ?c
FROM NAMED <http://AliceIRI>
FROM NAMED <http://BobIri>
FROM NAMED <http://CarlIri>
WHERE {
GRAPH ?g {
    <http://local.virt/foo> ?b ?c 
    FILTER( ?g=<http://AliceIRI> || ?g=<http://BobIri> )
}
}
Tinney answered 28/4, 2015 at 13:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.