如果路径不存在,则创建所有不存在的节点和边

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

我想将 Python 包的模块表示为 neo4j 图中的节点。我收到如下输入,如果尚未包含该模块,则必须更新图表。假设我的输入如下所示:

a.b.c.d
a.b.c.e
a
a.b.c
a.b

如果

a.b.c
已经存在,当我遇到
a.b.c.d
时我不想重新创建这些节点。我只想创建一个名为
d
的新节点并将其连接到
c
。同样,如果我得到
a.b.c
并且这些节点都不存在,那么我想创建所有节点并相应地连接它们。我的真实输入每条路径可以有任意数量的节点,所以我想要一个可以处理任意路径长度的 Cypher 查询。

我是 Cypher 新手。这是我的第一次尝试。

MERGE p=(module:Module {name: $module_name})
WITH p, module
MATCH (package:Module)-[:contains*]->(module)
WHERE [x in nodes(p) | x.name] = $module_path

但是,Cypher 给了我以下错误:

查询无法以 MATCH 结束

我也尝试过这个:

MERGE p=(:Module)-[:contains*]->(:Module)
WHERE [x in nodes(p) | x.name] = $module_path

但随后 Cypher 抱怨

WHERE
的存在。

请注意,我使用 neo4j Python 库来运行此查询,并传入如下参数:

{"module_path":["a","b","c"], "module_name":"c"}
。如果有更好的方法,我很高兴以不同的方式参数化我的查询,但我不认为这是我的错误的根源。

neo4j cypher
1个回答
0
投票

可以通过以下查询来实现(添加注释)

// simulate your input
WITH "a.b.c.d" AS pkg 
// split on the dot, producing an array 
WITH split(pkg, ".") AS parts ['a','b','c','d']
// iterating of the array
UNWIND parts AS part 
// MERGE (match or create) the module with the name as id ( up to you which property to use )
MERGE (m:Module {id: part}) 
// break and introduce a variable being an array of the nodes created or matched
WITH collect(m) AS modules 
// use APOC to link those nodes together with the NEXT relationship
CALL apoc.nodes.link(modules,'NEXT') 

它产生这样的图表

稍后,如果您尝试对已经存在的模块路径执行相同的操作,它将不会执行任何操作,例如在上述之后,以下查询将不会创建任何内容

WITH "a.b.c" AS pkg
WITH split(pkg, ".") AS parts
UNWIND parts AS part
MERGE (m:Module {id: part})
WITH collect(m) AS modules
CALL apoc.nodes.link(modules,'NEXT')

© www.soinside.com 2019 - 2024. All rights reserved.