在我的Neo4j应用程序中,我有一个复合Decision
节点。每个Decision
可以具有无限数量和深度的后代Decision
节点。
我有一个Cypher查询,它返回某个父决策ID的后代决策ID:
MATCH (d:Decision)-[:CONTAINS*]->(descendantDecision)
WHERE id(d) = {decisionId}
RETURN id(descendantDecision) as id
我需要修改此函数,以便仅返回非共享后代决策节点id。
例如,我有以下层次结构:
父D3
{decisionId}
的新Cypher查询必须返回以下后代决定ID:D4
,D6
,D7
,D8
< / p>
请注意,必须返回标识为D7
(与D4
和D8
共享)的共享节点,因为此节点仅在D3
内部层次结构内共享但已共享不得返回标识为D5
的节点,因为它与外部层次结构中的某个其他节点(D9
)共享到D3
。
因此,必须返回以下节点(标有绿色标志 - D4
,D6
,D7
,D8
):
请帮我创建这个新的Cypher查询。
答案 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