Neo4j - 基于 属性 创建节点之间的关系

Neo4j - Create relationship between nodes based on property

我在图表中有节点。节点有两种类型;让我们称它们为 group agroup b。我拥有 group agroup b 中节点之间关系的映射,它基于每个节点中的 name 属性。为清楚起见,映射文件看起来有点像这样:

(:a {name:'abc'})-[:RELATES_TO]->(:b {name:'def'}),
(:a {name:'abd'})-[:RELATES_TO]->(:b {name:'def'}),
...
(:a {name:'uvw'})-[:RELATES_TO]->(:b {name:'xyz'})

组之间的 name 不共享,所以我不能使用类似的东西:

MATCH (a),(b)
WHERE a.name = b.name
MERGE (a)-[:RELATES_TO]->(b)

由于现有节点包含多个属性,但映射仅包含name 属性,使用以下MERGE导致新节点的生成,而不是连接我现有的节点数:

MERGE
(:a {name:'abc'})-[:RELATES_TO]->(:b {name:'def'}),
(:a {name:'abd'})-[:RELATES_TO]->(:b {name:'def'}),
...
(:a {name:'uvw'})-[:RELATES_TO]->(:b {name:'xyz'})

我相信可以通过手动将所有属性添加到映射文件并 运行 上述合并来单独实现每个关系,但我相信添加关系的所有信息已经存在;我有每个关系的起点和终点。因此,我怀疑一定有更优雅的方法来解决这个问题。

在我过去使用 Neo4j 的经验中,上述问题的发生相当普遍 -> 我不清楚我是否缺少一些语法知识,这是一个简单的修复,或者我是否在滥用这种方式Neo4j 旨在运行,我需要重新考虑我是如何进行的。

问题可能是因为您MERGE整个模式,这将导致创建整个模式。 假设 name 属性作为唯一键,我建议你试试这个:

// make sure you have a list of a,b combinations, resulting from previous processing
a,b
'abc','def'
'abd','def'
...
'uvw','xyz''

// process these combinations
WITH a,b
MERGE (a:a {name:a})
MERGE (b:b {name:b})
MERGE (a)-[:RELATES_TO]->(b)

请注意,在 name 属性 上创建 CONSTRAINT 会加快速度。

假设您将两组节点的名称放在两个不同的数组中,但它们的长度相同,这将是一个有效的示例:

// these are the two arrays
WITH ['abc','abd','uvw'] AS aNodes, 
     ['def','def','xyz'] AS bNodes

// create an index for the array
UNWIND RANGE(0,size(aNodes)-1) AS i

//loop through the arrays to create a,b combinations
WITH aNodes[i] AS a,
     bNodes[i] AS b

// process these combinations
MERGE (n:a {name:a})
MERGE (m:b {name:b})
MERGE (n)-[:RELATES_TO]->(m)
RETURN *

首先 - 创建节点:

create
(:a {name:'abc'}),
(:a {name:'abd'}),
(:a {name:'uvw'}),
(:b {name:'def'}),
(:b {name:'def'}),
(:b {name:'xyz'})

其次 - 启用多语句编辑器

导航到设置。添加检查 Enable multi statement query editor

第三 - 为每个关系创建 Match/Merge 对

分号表示查询结束。这就是您如何利用多语句查询编辑器。

match(a:a {name:'abc'}),(b:b {name:'def'})
merge(a)-[:RELATES_TO]->(b);
match(a:a {name:'abd'}),(b:b {name:'def'})
merge(a)-[:RELATES_TO]->(b);
match(a:a {name:'uvw'}),(b:b {name:'xyz'})
merge(a)-[:RELATES_TO]->(b);