Graph¶
The walrus graph
module provides a lightweight hexastore implementation. The Graph
class uses Redis ZSet
objects to store collections of subject - predicate - object
triples. These relationships can then be queried in a very flexible manner.
Note
The hexastore logic is expecting UTF-8 encoded values. If you are using Python 2.X unicode text, you are responsible for encoding prior to storing/querying with those values.
For example, we might store things like:
charlie – friends – huey
charlie – lives – Kansas
huey – lives – Kansas
We might wish to ask questions of our data-store like “which of charlie’s friends live in Kansas?” To do this, we will store every permutation of the S-P-O triples, then we can efficiently query using the parts of the relationship we know beforehand.
query the “object” portion of the “charlie – friends” subject/predicate.
for each object returned, turn it into the subject of a second query whose predicate is “lives” and whose object is “Kansas”.
So we would return the subjects that satisfy the following expression:
("charlie -- friends") -- lives -- Kansas
Let’s go through this simple example to illustrate how the Graph
class works.
from walrus import Database
# Begin by instantiating a `Graph` object.
db = Database()
graph = db.graph('people')
# Store my friends.
# "charlie" is subject, "friends" is predicate, "huey" is object.
graph.store('charlie', 'friends', 'huey')
# Can also store multiple relationships at once.
graph.store_many((
('charlie', 'friends', 'zaizee'),
('charlie', 'friends', 'nuggie')))
# Store where people live.
graph.store_many((
('huey', 'lives', 'Kansas'),
('zaizee', 'lives', 'Missouri'),
('nuggie', 'lives', 'Kansas'),
('mickey', 'lives', 'Kansas')))
# We are now ready to search. We'll use a variable (X) to indicate
# the value we're interested in.
X = graph.v.X # Create a variable placeholder.
# In the first clause we indicate we are searching for my friends.
# In the second clause, we only want those friends who also live
# in Kansas.
results = graph.search(
{'s': 'charlie', 'p': 'friends', 'o': X},
{'s': X, 'p': 'lives', 'o': 'Kansas'})
print(results)
# Prints: {'X': {'huey', 'nuggie'}}
In the above example, the result value is a dictionary of variable values that satisfy the search expressions. The search()
method is quite powerful!
An even simpler example¶
Let’s say we wish only to retrieve a list of Charlie’s friends. In this case we do not need to use a variable. We can use the simpler query()
method. This method optionally takes a subject, predicate and/or object and, using the provided data, returns all objects that “match” the given pieces.
So to find Charlie’s friends, we would write:
query = graph.query(s='charlie', p='friends')
for result in query:
print(result['o']) # Print the object for the corresponding S/P.