Created
November 3, 2012 23:37
-
-
Save mhluongo/4009325 to your computer and use it in GitHub Desktop.
another neo4django relational filtering workaround
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# a hack for pete.groups.filter(created_date__gt = datetime.date(2012,1,1), type__type = "Chess Club") | |
import datetime | |
import neo4django | |
from neo4django.db import models | |
class Person(models.NodeModel): | |
auto_id = models.AutoProperty(indexed=True) | |
groups = models.Relationship('Group', related_name='people', | |
rel_type=neo4django.Outgoing.MEMBER_OF) | |
class Group(models.NodeModel): | |
group_type = models.Relationship('GroupType', related_name='groups', single=True, | |
rel_type=neo4django.Outgoing.TYPE_OF) | |
created_date = models.DateProperty(indexed=True) | |
class GroupType(models.NodeModel): | |
type = models.StringProperty(indexed=True, unique=True) | |
### all sorts of interesting data is inserted here ### | |
# one way to filter by relationship, now, is to do so in-memory. this is inefficient | |
# and hits the db too frequently, but for plenty of cases it's fine. | |
pete = Person.objects.get(auto_id=88) | |
petes_new_groups = pete.groups.all().filter(created_date__gt=datetime.date(2012,1,1)) | |
petes_new_chess_groups = [g for g in petes_new_groups if g.group_type.type == 'Chess Club'] | |
# unless the above has shown itself to be a bottleneck, I'd stick with it. | |
# however, the most efficient way until relationship-spanning lookups are implemented | |
# is to go straight to Cypher and then wrap the results in neo4django objects | |
from neo4django.db import connection | |
from neo4django.db.models.script_utils import LazyNode | |
cypher_query = """ | |
START pete=node({nodeId}) | |
MATCH pete-[:MEMBER_OF]->group-[:TYPE_OF]->group_type | |
WHERE (group_type.type = 'Chess Club' and group.created_date > "2012-01-01") | |
RETURN group | |
""" | |
table = connection.cypher(cypher_query, nodeId = pete.id) | |
petes_new_chess_groups = [Group._neo4j_instance(LazyNode.from_dict(r[0])) r for r in table['data']] | |
# there are a couple ways to make this better (eg already have the GroupType node id, or look it | |
up in the Cypher query) | |
# the real downside (outside of the ugliness) of this approach is the ignorance of how neo4django | |
# has indexed all of these objects, which are unique, etc, the knowledge of which could be used to | |
# speed up the query. that will have to wait on scholrly/neo4django#20 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment