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

qcbq4gxm  于 2023-10-18  发布在  其他
关注(0)|答案(3)|浏览(110)

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

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)

图中有两种节点-AccountCalculation账户节点与计算节点存在“RESULTS_FROM”关系,且名称+利息类型相同。计算节点与其他“n”个帐户节点具有“DEPENDS_ON”关系。
下面是图表的样子。

我需要写一个密码,它从一个账户节点开始,在整个图中找到它的所有依赖关系。此上下文中的依赖关系是计算节点“RESULTS_FROM”和这些计算节点“DEPENDS_ON”的帐户节点。它应该在所有方向上递归地执行此操作,直到找到一个与任何其他Calculation节点都没有任何“RESULTS_FROM”关系的Account节点。
在快照中,如果我从“account.B”开始,它将遵循“RESULTS_FROM”关系(通过蓝色计算节点),然后通过“DEPENDS_ON”指向“account.y”和“account. c”。
所以输出应该是- account.y和account. c
类似地,“account.x”的输出应该是“account.d”。当任何帐户不执行任何计算时,我们停止。
我尝试了不同的东西,如下面,但我不知道什么是理想的方式来做到这一点。

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-这里的数据只是一个示例,实际上,图表将有100个帐户和计算节点。但节点之间的关系保持不变。并且没有计算节点将依赖于具有相同名称+ interest_type的帐户节点

rwqw0loc

rwqw0loc1#

您可以通过使用量化的路径模式来更具体地了解您正在寻找的模式:

MATCH (:Account {name:'account.b'}) 
      (()-[:RESULTS_FROM]->(:Calculation)-[:DEPENDS_ON]->(:Account))+ (n)
RETURN collect(n)

更具体的模式通常意味着更快。

oxosxuxt

oxosxuxt2#

一个选择是使用APOC。其中一个优点是它很容易只给你想要的“端”节点:

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

返回:

╒════════════════════════════════════════════════════════════════╕
│nodes                                                           │
╞════════════════════════════════════════════════════════════════╡
│[(:Account {name: "account.y"}), (:Account {name: "account.c"})]│
└────────────────────────────────────────────────────────────────┘

**编辑:**根据@cybersam的评论,relationshipFilter>更改为RESULTS_FROM>|DEPENDS_ON>

cgvd09ve

cgvd09ve3#

您可以使用可变长度关系来查找所有与指定模式匹配的节点(CalculationAccount节点):

MATCH (:Account {name: 'account.b'})-[:RESULTS_FROM|DEPENDS_ON*]->(n)
RETURN n

如果你只需要Account节点,可以使用这个:

MATCH (:Account {name: 'account.b'})-[:RESULTS_FROM|DEPENDS_ON*]->(n:Account)
RETURN n

相关问题