Michael
Michael

Reputation: 715

Neo4j cypher - filter out child nodes

Imagine the following graph:

enter image description here

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

Answers (3)

cybersam
cybersam

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

stdob--
stdob--

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

Bruno Peres
Bruno Peres

Reputation: 16365

I reproduced your scenario using this sample data set:

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

Related Questions