合并节点

APOC 库包含一个可用于合并节点的过程。

此过程允许将节点列表合并到列表中的第一个节点(所有关系也会合并到该节点)。合并行为可以全局或单独指定属性。

合并节点的过程

限定名称 类型

apoc.refactor.mergeNodes(nodes LIST<NODE>, config MAP<STRING, ANY>) - 将给定的 LIST<NODE> 合并到 LIST<NODE> 中的第一个 NODE 上。所有 RELATIONSHIP 值也都会合并到该 NODE 上。

过程

MATCH (p:Person)
WITH p ORDER BY p.created DESC // newest one first
WITH p.email AS email, collect(p) as nodes
CALL apoc.refactor.mergeNodes(nodes, {properties: {
    name:'discard',
    age:'overwrite',
    kids:'combine',
    `addr.*`: 'overwrite',
    `.*`: 'discard'
}})
YIELD node
RETURN node

配置选项

以下是此过程的配置选项:这些配置选项也适用于 apoc.refactor.mergeRelationships([rels],{config})

类型 操作

丢弃

如果已设置,则保留第一个节点的属性;否则写入列表中的第一个属性

覆盖 / 重写

列表中最后一个属性胜出

组合

如果列表中只有一个属性,则将其设置为/保留为单个属性,否则创建一个数组,并尝试强制转换值

此外,mergeNodes 支持以下配置属性

类型 操作

mergeRels

true/false:允许合并具有相同类型和方向的关系。

produceSelfRel

true/false:如果为 true(默认),则插入由合并到目标节点中的节点创建的任何最终新的自循环关系,否则不插入。请注意,此参数独立于 mergeRels 配置,并且不影响预先存在的自循环关系(在这种情况下使用 preserveExistingSelfRels 配置)。

preserveExistingSelfRels

true/false:仅在 mergeRels:true 时有效。如果为 true(默认),则最终节点中预先存在的自循环关系将保留,否则将被删除。

singleElementAsArray

false/true:如果为 false(默认),并且 typecombine,则在两个数组合并为一个大小为 1 的新数组时,它会提取单个值。

未包含在配置映射中的属性将被覆盖。

关系属性使用相同的方法管理,除非配置映射为空,在这种情况下实体属性将被组合。

示例

以下示例将进一步解释此过程。

相同的起始和结束节点

以下创建一个包含具有相同起始和结束节点的关系的图
CREATE (n1:Person {name:'Tom'}),
(n2:Person {name:'John'}),
(n3:Company {name:'Company1'}),
(n5:Car {brand:'Ferrari'}),
(n6:Animal:Cat {name:'Derby'}),
(n7:City {name:'London'}),

(n1)-[:WORKS_FOR {since:2015}]->(n3),
(n2)-[:WORKS_FOR {since:2018}]->(n3),
(n3)-[:HAS_HQ {since:2004}]->(n7),
(n1)-[:DRIVE {since:2017}]->(n5),
(n2)-[:HAS {since:2013}]->(n6);
return *;
apoc.refactor.mergeNodes.createDataSetFirstExample
以下将 John 和 Tom 合并为一个节点
MATCH (a1:Person{name:'John'}), (a2:Person {name:'Tom'})
WITH head(collect([a1,a2])) as nodes
CALL apoc.refactor.mergeNodes(nodes,{properties:"combine", mergeRels:true})
YIELD node
RETURN count(*)

如果运行上述查询,将得到以下图

apoc.refactor.mergeNodes.resultFirstExample

由于关系具有相同的起始和结束节点,因此关系被合并,属性被组合。

不同的起始和结束节点

以下创建一个包含具有不同起始或结束节点的关系的图
Create (n1:Person {name:'Tom'}),
(n2:Person {name:'John'}),
(n3:Company {name:'Company1'}),
(n4:Company {name:'Company2'}),
(n5:Car {brand:'Ferrari'}),
(n6:Animal:Cat {name:'Derby'}),
(n7:City {name:'London'}),
(n8:City {name:'Liverpool'}),
(n1)-[:WORKS_FOR{since:2015}]->(n3),
(n2)-[:WORKS_FOR{since:2018}]->(n4),
(n3)-[:HAS_HQ{since:2004}]->(n7),
(n4)-[:HAS_HQ{since:2007}]->(n8),
(n1)-[:DRIVE{since:2017}]->(n5),
(n2)-[:HAS{since:2013}]->(n6)
return *;
apoc.refactor.mergeNodes.createDataSetSecondExample
以下将 John 和 Tom 合并为一个节点
MATCH (a1:Person{name:'John'}), (a2:Person {name:'Tom'})
WITH head(collect([a1,a2])) as nodes
CALL apoc.refactor.mergeNodes(nodes,{
    properties:"combine",
    mergeRels:true
})
YIELD node
RETURN count(*)

如果运行上述查询,将得到以下图

apoc.refactor.mergeNodes.resultSecondExample
apoc.refactor.mergeNodes.resultSecondExampleData

由于关系具有不同的结束节点,因此所有关系和属性都将保留。