合并节点
APOC 库包含一个可用于合并节点的存储过程。
此过程允许将节点列表合并到列表中的第一个节点上(所有关系也会合并到该节点上)。可以全局和/或单独指定属性的合并行为。
合并节点的存储过程
| 限定名称 | 类型 |
|---|---|
|
过程 |
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})。
| type | 操作 |
|---|---|
discard |
如果第一个节点中已设置属性,则保留该属性,否则写入列表中的第一个属性 |
overwrite / override |
列表中的最后一个属性胜出 |
combine |
如果列表中只有一个属性,则将其设置/保留为单个属性,否则创建一个数组,并尝试强制转换值 |
此外,mergeNodes 支持以下配置属性
| type | 操作 |
|---|---|
mergeRels |
true/false:允许合并具有相同类型和方向的关系。 |
produceSelfRel |
true/false:如果为 |
preserveExistingSelfRels |
true/false:仅在 |
singleElementAsArray |
false/true:如果为 |
配置映射中未包含名称的属性将被覆盖。
关系属性使用相同的方法进行管理,除非配置映射为 null,在这种情况下,实体属性会被合并。
示例
以下示例将进一步解释此过程。
相同的起始和结束节点
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 *;
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(*)
如果运行上述查询,将得到以下图形
由于这些关系具有相同的起始和结束节点,因此关系被合并,属性被组合。
不同的起始和结束节点
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 *;
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(*)
如果运行上述查询,将得到以下图形
由于关系具有不同的结束节点,因此保留了所有关系和属性。