Reputation: 715
Imagine the following graph:
The goal is to query for all connecting nodes between two entities ("Main" and "Other" in this case), but filter out mutual descendants. In other words, I would like the result set to only contain a and b, but not c, because C is a descendant of B, which is already included in the result set.
Upvotes: 1
Views: 480
Reputation: 66999
This query collects all the direct descendants of the 2 entities, and then filters out the ones that have a direct descendant as a parent:
MATCH (:Node {name : "Main"})-[:child]->(child:Node)<-[:child]-(:Node {name : "Other"})
WITH COLLECT(child) AS children
UNWIND children AS c
MATCH (c)<-[:child]-(parent:Node)
WITH c, children, COLLECT(parent) AS parents
WHERE NONE(p IN parents WHERE p IN children)
RETURN c;
Upvotes: 0
Reputation: 29172
If I correctly understand the condition of the problem, then you need to find such child nodes, to which exactly one way to get from the original nodes:
MATCH p = (Main:Node {id: 'main'})
-[:child*]->(T:Node)<-[:child*]-
(Other:Node {id: 'other'})
WITH T,
collect(p) as pw WHERE size(pw) = 1
RETURN T
Upvotes: 0
Reputation: 16365
I reproduced your scenario using this sample data set:
This query should work:
// match common child nodes between 'main' and 'other'
MATCH (:Node {name : "Main"})-[:child]->(child:Node)<-[:child]-(:Node {name : "Other"})
// match the children of child when exists
OPTIONAL MATCH (child)-[:child]->(n:Node)
// store children and childrenOfChild in separeted arrays
WITH collect(child) as children, collect(n) as childrenOfChild
// filter ...
WITH filter(child in children WHERE NOT child IN childrenOfChild) as directChildren
UNWIND directChildren as directChild
// return only direct child
RETURN directChild
The output:
╒═════════════╕
│"directChild"│
╞═════════════╡
│{"name":"b"} │
├─────────────┤
│{"name":"a"} │
└─────────────┘
Upvotes: 1