【问题标题】:Neo4j Cypher non-shared descendant nodesNeo4j Cypher 非共享后代节点
【发布时间】:2015-09-26 10:38:12
【问题描述】:

在我的 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:D4D6D7D8

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

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

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

【问题讨论】:

    标签: neo4j cypher


    【解决方案1】:

    这里的相关标准是结果集的每个成员只能具有来自作为原始节点后代的节点的入站关系。所以语句看起来像:

    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

    【讨论】:

      【解决方案2】:

      这是@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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-03-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多