如何编写一个密码查询来递归遍历 Neo4j 中的图以查找所有访问过的节点

问题描述 投票:0回答:1

我使用下面的密码在本地的 docker 容器中运行的 neo4j 社区版中创建了一个图表。

create (a:Account{name:'account.a'}),
(b:Account{name:'account.b'}),
(c:Account{name:'account.c'}),
(d:Account{name:'account.d'}),
(e:Account{name:'account.e'}),
(f:Account{name:'account.f'}),
(x:Account{name:'account.x'}),
(y:Account{name:'account.y'}),
(cas:Calculation{name:'account.a:simple_interest'}),
(cac:Calculation{name:'account.a:compound_interest'}),
(cbs:Calculation{name:'account.b:simple_interest'}),
(cbc:Calculation{name:'account.b:compound_interest'}),
(cxs:Calculation{name:'account.x:simple_interest'}),
(cxc:Calculation{name:'account.x:compound_interest'}),
(a)-[:RESULTS_FROM]->(cas),
(a)-[:RESULTS_FROM]->(cac),
(b)-[:RESULTS_FROM]->(cbs),
(b)-[:RESULTS_FROM]->(cbc),
(x)-[:RESULTS_FROM]->(cxs),
(x)-[:RESULTS_FROM]->(cxc),
(cas)-[:DEPENDS_ON]->(d),
(cas)-[:DEPENDS_ON]->(e),
(cbs)-[:DEPENDS_ON]->(c),
(cbc)-[:DEPENDS_ON]->(y),
(cac)-[:DEPENDS_ON]->(f),
(cac)-[:DEPENDS_ON]->(d),
(cxs)-[:DEPENDS_ON]->(d),
(cxc)-[:DEPENDS_ON]->(d)

图中有两种节点 - AccountCalculationAccount 节点与具有相同名称+兴趣类型的 Calculation 节点具有“RESULTS_FROM”关系。 Calculation 节点与“n”个其他 Account 节点具有“DEPENDS_ON”关系。

下图是图表的样子。

我需要编写一个从帐户节点开始的密码,并在整个图中找到它的所有依赖项。此上下文中的依赖项是其“RESULTS_FROM”的计算节点以及这些计算节点“DEPENDS_ON”的帐户节点。它应该在所有方向上递归地执行此操作,直到找到与任何其他计算节点没有任何“RESULTS_FROM”关系的帐户节点。

在快照中,如果我从“account.b”开始,它将遵循“RESULTS_FROM”关系(通过蓝色计算节点),然后通过“DEPENDS_ON”指向“account.y”和“account.c”。

所以输出应该是 - account.y 和 account.c

类似地,“account.x”的输出应该是“account.d”。当任何帐户未“RESULT_FROM”任何计算时,我们就会停止。

我尝试了如下不同的方法,但我不确定执行此操作的理想方法是什么。

MATCH (startNode:YourLabel {name: 'account.a'})
CALL {
  WITH [startNode] AS nodes, [] AS rels
  UNWIND nodes AS node
  FOREACH(ignoreMe IN [1] |
    MATCH (node)-[r]->(relatedNode)
    WHERE NOT relatedNode IN nodes
    SET nodes = nodes + relatedNode
    SET rels = rels + r
  )
}
RETURN DISTINCT nodes AS reachableNodes

ps-这里的数据只是一个示例,实际上,该图表将有数百个帐户和计算节点。但节点之间的关系保持不变。并且任何计算节点都不会依赖于具有相同名称+interest_type的帐户节点

neo4j cypher
1个回答
0
投票

一个选项是使用

APOC
:

MATCH(n:Account{name:'account.b'})
CALL apoc.path.subgraphAll(n, {
    relationshipFilter:">",
    labelFilter: ">Account"
})
YIELD nodes
RETURN nodes

返回:

╒════════════════════════════════════════════════════════════════╕
│nodes                                                           │
╞════════════════════════════════════════════════════════════════╡
│[(:Account {name: "account.y"}), (:Account {name: "account.c"})]│
└────────────────────────────────────────────────────────────────┘
© www.soinside.com 2019 - 2024. All rights reserved.