Querying

Querying should be easy for anyone familiar with Django. Model managers return a subclass of QuerySet that converts queries into the Cypher graph query language, which yield NodeModel instances on execution.

Most of the Django QuerySet API is implemented, with exceptions noted in the project issues. In particular, the library doesn’t yet support relationship-spanning lookups or complex date handling. We’ve also added two field lookups- member and member__in- to make searching over array properties easier. For an OnlinePerson instance with an emails property, query against the field like:

OnlinePerson.objects.filter(emails__member="wicked_cool_email@example.com")

JOINs

It’s important to remember that, since we’re using a graph database, “JOIN-like” operations are much less expensive. Consider a more connected model:

class FamilyPerson(Person):
    parents = Relationship('self', rel_type='child_of')
    stepdad = Relationship('self', rel_type='step_child_of', single=True)
    siblings = Relationship('self', rel_type='sibling_of')
    # hopefully this is one-to-one...
    spouse = Relationship('self', rel_type='married_to', single=True, rel_single=True)

If we’d like to pre-load a subgraph around a particular FamilyPerson, we can use select_related():

jack = Person.objects.all(name='Jack').select_related(depth=5)
#OR
Person.objects.get(name='Jack').select_related('spouse__mother__sister__son__stepdad')

...either of which will pre-load Jack’s extended family so he can go about recalling names without hitting the database a million times.