Range queries — AllegroGraph Python client 104.2.0 documentation (original) (raw)

Example 15: Range queries

In many of the previous examples we have used thegetStatements() method to find all triples conforming to a given pattern. The patterns we have used so far matched each triple component against a single value. It is possible to use more complex patterns that can match a range of values for each component. To illustrate this let us first create a connection:

from franz.openrdf.connect import ag_connect

conn = ag_connect("python-tutorial", create=True, clear=True)

and construct some data:

conn.addData(""" @prefix : ex:// .

:mercury a :planet ; :moons 0 .
:venus a :planet ; :moons 0 .
:earth a :planet ; :moons 1 .
:mars a :planet ; :moons 2 .
:jupiter a :planet ; :moons 67 .
:saturn a :planet ; :moons 62 .
:uranus a :planet ; :moons 27 .
:neptune a :planet ; :moons 14 .
:pluto a :dwarf_planet ; :moons 5 .

""")

Suppose that we want to locate all planets that have at least one, but no more than five moons. To issue such a query we need to create aRange object:

one_to_five = conn.createRange(1, 5)

We can pass the range object to getStatements():

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

This will find two planets and one dwarf planet, as expected:

ex://earth ex://mars ex://pluto

The arguments to createRange() can be either RDF terms or regular Python values that will be converted to typed literals. In our example we used have used values of type int, which will be mapped to literals of type<http://www.w3.org/2001/XMLSchema#integer>. Range queries will only match values of exactly the same type. For instance if we add another triple to our store:

conn.addData(""" @prefix : ex:// . @prefix xsd: http://www.w3.org/2001/XMLSchema# .

:coruscant a :planet ; :moons "4"^^xsd:long .

""")

And then reissue our query:

with conn.getStatements( None, moons, one_to_five) as result: for statement in result: print(statement.getSubject())

we will find that the result has not changed:

ex://earth ex://mars ex://pluto

Range queries can also be performed with SPARQL, using FILTER:

conn.executeTupleQuery(''' SELECT ?planet { ?planet ex://moons ?moons . filter (?moons <= 5 && ?moons >= 1) }''', output=True)

The result is the same as in the previous example.


| planet |

| ex://coruscant | | ex://earth | | ex://mars | | ex://pluto |

When the filter expression is a simple set of inequalities, as it is in this case, the query engine will use indices to optimize the query execution, similaraly to the way getStatements() does for range queries.