I am using the py2neo.ogm
api to construct queries of my IssueOGM
class based on its relationship to another class.
I can see why this fails:
>>> list(IssueOGM.select(graph).where(
... "_ -[:HAS_TAG]- (t:TagOGM {tag: 'critical'})"))
Traceback (most recent call last):
...
py2neo.database.status.CypherSyntaxError: Variable `t` not defined (line 1, column 42 (offset: 41))
"MATCH (_:IssueOGM) WHERE _ -[:HAS_TAG]- (t:TagOGM {tag: 'critical'}) RETURN _"
Is there a way using the OGM api to create a filter that is interpreted as this?
"MATCH (_:IssueOGM) -[:HAS_TAG]- (t:TagOGM {tag: 'critical'}) RETURN _"
Like an ORM, the OGM seems to be really good for quickly storing and/or retrieving nodes from your graph, and saving special methods and so forth to make each node 'work' nicely in your application. In this instance, you could use the RelatedFrom
class on TagOGM
to list all the issues tagged with a particular tag. However, this approach can sometimes lead to making lots of inadvertent db calls without realising (especially in a big application).
Often for cases like this (where you're looking for a pattern rather than a specific node), I'd recommend just writing a cypher query to get the job done. py2neo.ogm
actually makes this remarkably simple, by allowing you to store it as a class method of the GraphObject
. In your example, something like the following should work. Writing similar queries in the future will also allow you to search based on much more complex criteria and leverage the functionality of neo4j and cypher to make really complex queries quickly in a single transaction (rather than going back and forth to the db as you manipulate an OGM object).
from py2neo import GraphObject, Property
class TagOGM(GraphObject):
name = Property()
class IssueOGM(GraphObject):
name = Property()
time = Property()
description = Property()
@classmethod
def select_by_tag(cls, tag_name):
'''
Returns an OGM instance for every instance tagged a certain way
'''
q = 'MATCH (t:TagOGM { name: {tag_name} })<-[:HAS_TAG]-(i:IssueOGM) RETURN i'
return [
cls.wrap(row['i'])
for row in graph.eval(q, { 'tag_name': tag_name }).data()
]