Neo4j Cypher非共享后代节点

时间:2015-09-26 10:38:13

标签: neo4j cypher

在我的Neo4j应用程序中,我有一个复合Decision节点。每个Decision可以具有无限数量和深度的后代Decision节点。

我有一个Cypher查询,它返回某个父决策ID的后代决策ID:

MATCH (d:Decision)-[:CONTAINS*]->(descendantDecision) 
WHERE id(d) = {decisionId} 
RETURN id(descendantDecision) as id

我需要修改此函数,以便仅返回非共享后代决策节点id。

例如,我有以下层次结构:

enter image description here

D3 {decisionId}的新Cypher查询必须返回以下后代决定ID:D4D6D7D8 < / p>

请注意,必须返回标识为D7(与D4D8共享)的共享节点,因为此节点仅在D3内部层次结构内共享但已共享不得返回标识为D5的节点,因为它与外部层次结构中的某个其他节点(D9)共享到D3

因此,必须返回以下节点(标有绿色标志 - D4D6D7D8):

enter image description here

请帮我创建这个新的Cypher查询。

2 个答案:

答案 0 :(得分:3)

此处的相关标准是结果集的每个成员必须仅具有来自节点的入站关系,这些节点是原始节点的后代。所以声明如下:

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

为了完整起见,我为此创建了一个neo4j控制台设置:http://console.neo4j.org/?id=ufyu0u

答案 1 :(得分:3)

以下是@ sarmbruster建议的替代变体:

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