H. Trujillo
H. Trujillo

Reputation: 437

How to return data in cypher using a condition?

I have a relationship in Neo4j that looks something like thisenter image description here

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

Answers (2)

InverseFalcon
InverseFalcon

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

Dave Bennett
Dave Bennett

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

Related Questions