Example 7: Querying multiple contexts

The purpose of this example is to see how data imported into multiple contexts (like that from Example 6: Importing triples) behaves when queried using various methods. This exampe covers only the results of basic queries. The subject is explored in more detail in Example 10: Graphs in SPARQL.

Let us start by creating a few triples in the default context:

from franz.openrdf.query.query import QueryLanguage

conn = connect()
conn.addData("""
   <ex://default1> <ex://p1> 1 .
   <ex://default2> <ex://p2> 2 .
   <ex://default3> <ex://p3> 3 .""")

We can add data to another contect by using the optional context parameter of addData():

context = conn.createURI('ex://context')
conn.addData("""
   <ex://context1> <ex://p1> 1 .
   <ex://context2> <ex://p2> 2 .
   <ex://context3> <ex://p3> 3 .""",
   context=context)

Let’s try a getStatements() call first:

p1 = conn.createURI('ex://p1')
with conn.getStatements(None, p1, None, None) as result:
    for row in result:
        print(row.getSubject())

This loop prints out a mix of triples from the default context and from the named context.

<ex://context1>
<ex://default1>

SPARQL queries behave in a different way. When a graph clause is present, as in the following code, triples that are not in a named context will not be examined:

query_string = """
    SELECT DISTINCT ?s WHERE {
      graph ?g { ?s ?p ?o filter(?o > 2).
    }} order by ?s"""
tuple_query = conn.prepareTupleQuery(
    QueryLanguage.SPARQL, query_string)
with tuple_query.evaluate() as result:
    for bindings in result:
        print(bindings[0])

Only the context3 triple is printed:

<ex://context3>

What happens if we issue a trivial query without mentioning graph?

query_string = """
    SELECT DISTINCT ?s WHERE {
      ?s ?p ?o .
    } order by ?s"""
tuple_query = conn.prepareTupleQuery(
    QueryLanguage.SPARQL, query_string)
with tuple_query.evaluate() as result:
    for bindings in result:
        print(bindings[0])

This prints all triples, just like a getStatements() call.

<ex://context1>
<ex://context2>
<ex://context3>
<ex://default1>
<ex://default2>
<ex://default3>

But this behavior can be altered by setting a query option. AllegroGraph allows such options to be set by defining a prefix.

query_string = """
    PREFIX franzOption_defaultDatasetBehavior: <franz:rdf>
    SELECT DISTINCT ?s WHERE {
      ?s ?p ?o .
    } order by ?s"""
tuple_query = conn.prepareTupleQuery(
    QueryLanguage.SPARQL, query_string)
with tuple_query.evaluate() as result:
    for bindings in result:
        print(bindings[0])

Now only the default context is matched by simple pattern (i.e. ones not wrapped in graph ?g { ... })

<ex://default1>
<ex://default2>
<ex://default3>