Being relatively new to Neo4j, I'm trying to find certain nodes with Cypher in a Neo4j graph database. The nodes should be connected by a chain of relationships of a certain type with further conditions on the relationships:
// Cypher
START self = node(3413)
MATCH (self)<-[rel:is_parent_of*1..100]-(ancestors)
WHERE rel.some_property = 'foo'
RETURN DISTINCT ancestors
If I drop the depth part *1..100
, the query works, but of course, then allows only one relationship between self
and the ancestors
.
But, if I allow the ancestors
to be several steps away from self
by introducing the depth *1..100
, the query fails:
Error: Expected rel
to be a Map but it was a Collection
I thought, maybe this syntax defines rel
to be is_parent_of*1..100
rather than defining rel
to be a relationship of type is_parent_of
and allowing a larger relationship depth.
So, I've tried to make my intentions clear by using parenthesis: [(rel:is_parent_of)*1..100
. But this causes a syntax error.
I'd appreciate any help to fix this. Thanks!
Calling *1..100
depth originates in the nomenclature of the neography ruby gem, where this is done using the abstract depth
method.
In neo4j, this is called variable length relationships, as can be seen here in the documentation: MATCH / Variable length relationships.
The reason for the "Expected rel
to be a Map but it was a Collection" error is, indeed, that rel
does not refer to each single relationship but rather to the entire collection of matched relationships.
For an example, see here in the documentation: MATCH / Relationship variable in variable length relationships.
First, acknowledge that the identifier refers to a collection (i.e. a set of multiple items) and call it rels
instead of rel
. Then, in the WHERE
clause, state that the condition has to apply to all rel
items in the rels
collection using the ALL
predicate.
// Cypher
START self = node(3413)
MATCH (self)<-[rels:is_parent_of*1..100]-(ancestors)
WHERE ALL (rel in rels WHERE rel.some_property = 'foo')
RETURN DISTINCT ancestors
The ALL predicate is explained here in the documentation: Functions / Predicate Functions.
I was led to this solution by this stackoverflow answer of a related question.
Unfortunately, asking for relationship properties does cost a lot of time. The above query with only a couple of nodes in the database, takes over 3000ms on my development machine.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With