cancel
Showing results for 
Search instead for 
Did you mean: 

Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.

How to find the closest common parent?

depire
Node Clone

Hello,
I assume my problem is not a new one, but I can't find an elegant solution.
merge (A:LEU {LEID: "A"})
merge (B:LEU {LEID: "B"})
merge (c:LEU {LEID: "C"})
merge (aa:LEU {LEID: "AA"})

merge (a)-[:CONTROLS {share:toFloat(100.0)}]->(b)
merge (a)-[:CONTROLS {share:toFloat(100.0)}]->(c)
merge (aa)-[:CONTROLS {share:toFloat(100.0)}]->(a)

I run the following code, it works.

MATCH (n:LEU)

WHERE (:LEU{LEID:"B"})<-[:CONTROLS0..]-(n) and (:LEU{LEID:"C"})<-[:CONTROLS0..]-(n)

RETURN collect(n)[0] as nn

My demand is about how to create dynamically the WHERE condition. I try the following, but it doesn't work. I assume that I must mix UNWIND, WHERE or FOREACH but how ?
MATCH (n:LEU)
WHERE EXISTS((n:LEU)<-[:CONTROLS]-(:LEU)) and NOT EXISTS((:LEU)<-[:CONTROLS]-(n:LEU))
WITH collect(n) as children
UNWIND children as child
MATCH (parent:LEU)
WHERE (child)<-[:CONTROLS*0..]-(parent)
RETURN parent

1 ACCEPTED SOLUTION

depire
Node Clone

Here is my solution, one can takes directly the first common parent.
MATCH (n:LEU)
WHERE EXISTS((n:LEU)<-[:CONTROLS]-(:LEU)) and NOT EXISTS((:LEU)<-[:CONTROLS]-(n:LEU))
WITH collect(n) as children
MATCH (first_common_parent:LEU)
WHERE ALL(child in children WHERE ((child)<-[:CONTROLS*0..]-(first_common_parent)))
RETURN collect(first_common_parent)[0]

"Dynamically" means that the user mustn't enter manually the children.

That may be could be useful for somelse.

View solution in original post

5 REPLIES 5

intouch_vivek
Graph Steward

Hi @depire,

Please explain what do you mean by dynamic Where ..
If you tells us exactly what the requirement is then group can help you much better way

ameyasoft
Graph Maven

Here is your starting scenario:

2X_b_bb3c6686eaebf3daf5b546c5df359043e0653375.png

Query:
MATCH (b:LEU)-[:CONTROLS]->(n:LEU)
with collect(n) as nm
unwind nm as nm1
RETURN nm1

Result:

2X_6_6511d6e4eac4e83084bcd78ba9bb12356148ea6f.png

Query:

MATCH (b:LEU)-[:CONTROLS]->(n:LEU)
WHERE NOT EXISTS ((n)-[:CONTROLS]->(:LEU))
with collect(n) as nm
unwind nm as nm1
RETURN nm1

Result:

2X_0_0de682f02bdd284096423bc93c97b5b003cb4b41.png

Query:

MATCH (n:LEU)
WHERE EXISTS ((:LEU)-[:CONTROLS]->(n))
AND NOT EXISTS ((n)-[:CONTROLS]->(:LEU))
WITH collect(n) as children
UNWIND children as child
MATCH (parent:LEU)
WHERE (child)<-[:CONTROLS*0..]-(parent)
RETURN parent

Result:

Hope this helps.

depire
Node Clone

Here is my solution, one can takes directly the first common parent.
MATCH (n:LEU)
WHERE EXISTS((n:LEU)<-[:CONTROLS]-(:LEU)) and NOT EXISTS((:LEU)<-[:CONTROLS]-(n:LEU))
WITH collect(n) as children
MATCH (first_common_parent:LEU)
WHERE ALL(child in children WHERE ((child)<-[:CONTROLS*0..]-(first_common_parent)))
RETURN collect(first_common_parent)[0]

"Dynamically" means that the user mustn't enter manually the children.

That may be could be useful for somelse.

That's really great that you solved the problem by yourself .
Please mark the post as solution so that others could use it

match (a:LEU)-[r:CONTROLS]-(b:LEU)
with a, count(r) as cnt where cnt > 1
return a

This returns node "A"