Reputation: 437
I have a relationship in Neo4j that looks something like this
Where (A)-[:Relationship]->(B) and (B)-[:Relationship]->(C) use the same relationship (in this case :Relationship), and I want to write a cypher query with a condition so that if the count of second level relationships (A)->(C) is greater than x, then don'd display (B)->(C), ie only display (A)->(B).
I tried to do something like:
MATCH(A) WHERE id(A)={id}
OPTIONAL MATCH p=(A)-[:Relationship]->(B)
OPTIONAL MATCH q=(A)-[:Relationship]->(B)-[:Relationship]->(C)
RETURN A, p, CASE WHEN COUNT(q)<10 THEN q ELSE [] END AS foo
The problem was foo was always q
Upvotes: 4
Views: 5187
Reputation: 30407
Have you tried simply adding a WHERE on your OPTIONAL MATCH so it will only display when the number of relationships is below your threshold?
MATCH(A) WHERE id(A)={id}
OPTIONAL MATCH p=(A)-[:Relationship]->(B)
OPTIONAL MATCH q=(A)-[:Relationship]->(B)-[:Relationship]->(C)
WHERE size((B)-[:Relationship]->()) < 10
RETURN A, p, CASE WHEN q IS NULL THEN [] ELSE q END AS foo
It's important to remember that WHERE clauses only apply to the previous MATCH, OPTIONAL MATCH, or WITH, so in this case, the OPTIONAL MATCH will fail and q
will be null when the number of secondary relationships from B
exceeds your threshold.
Upvotes: 0
Reputation: 11216
Have you considered matching an arbitrary path with a maximum length? Something along these lines?
MATCH path=(n:Node {name: {id} })-[:RELATIONSHIP*0..9]->(:Node)
RETURN PATH
Alternatively, you could use APOC which would allow you to parameterize the depth of the path.
MATCH (one:Node {name : {id} })
CALL apoc.path.expand(one, "RELATIONSHIP>", "+Node", 0, {n}) YIELD path AS p
return p
If you wanted to find all of the nodes at a particular depth {n}
from a starting node but then only return them if they were less than a specific threshold {lim}
then you could do something like this
MATCH (one:Node {name : {id} })
CALL apoc.path.expand(one,"RELATIONSHIP>","+Node", 0, {n}) yield path as p
WITH collect(nodes(p)[{n}]) AS nodes_at_depth
RETURN
CASE
WHEN size(nodes_at_depth) < {lim} then nodes_at_depth
ELSE []
END AS nodes_at_depth
Alternatively, you could just return the first {lim}
nodes at that depth
MATCH (one:Node {name : {id} })
CALL apoc.path.expand(one,"RELATIONSHIP>","+Node", 0, {n}) yield path as p
WITH collect(nodes(p)[{n}]) AS nodes_at_depth
RETURN nodes_at_depth[0..{lim}]
Upvotes: 1