Reputation: 25842
In my Neo4j application I have a composite Decision
node. Each Decision
can have an unlimited number and depth of descendant Decision
nodes.
I have a Cypher query that returns descendant decision id's for a certain parent decision id:
MATCH (d:Decision)-[:CONTAINS*]->(descendantDecision)
WHERE id(d) = {decisionId}
RETURN id(descendantDecision) as id
I need to modify this function in order to return only non-shared descendant decision nodes id's.
For example I have a following hierarchy:
The new Cypher query for parent D3
{decisionId}
must return following descendant decisions id's : D4
, D6
, D7
, D8
Please note that shared node with id D7
(shared with D4
and D8
) must be returned because this node is only shared inside of D3
inner hierarchy but shared node with id D5
must not be returned because it is shared with some other node (D9
) from an external hierarchy to D3
.
So, the following nodes(marked with a green sign - D4
, D6
, D7
, D8
) must be returned:
Please help me to create this new Cypher query.
Upvotes: 0
Views: 172
Reputation: 41706
Here is an alternative variant to @sarmbruster's suggestion:
MATCH (d:Decision)-[:CONTAINS*0..]->(descendantDecision)
WHERE d.name=3
WITH collect(DISTINCT descendantDecision) AS allDescendants
UNWIND allDescendants AS descendant
WITH allDescendants, descendant
WHERE ALL (p IN (descendant)<-[:CONTAINS]-()
WHERE last(nodes(p)) IN allDescendants)
RETURN descendant
Upvotes: 3
Reputation: 39925
The relevant criteria here is that each member of the result set must only have inbound relationships from nodes being descendents of the original node. So the statement looks like:
MATCH (d:Decision)-[:CONTAINS*0..]->(descendantDecision)
WHERE d.name=3
WITH collect(descendantDecision) AS allDescendants
UNWIND allDescendants AS descendant
MATCH (descendant)<-[:CONTAINS]-(parent)
WITH descendant, collect(parent) AS parents, allDescendants
WHERE ALL (x IN parents WHERE x IN allDescendants) // check if all inbound start at a descendant
RETURN descendant
For completeness I've created a neo4j console setup for this: http://console.neo4j.org/?id=ufyu0u
Upvotes: 3