介绍
该MERGE子句要么匹配图形中现有的节点模式并绑定它们,要么在不存在的情况下创建新数据并绑定它。这样,它充当和的组合,MATCH允许CREATE根据指定的数据是匹配还是创建来执行特定操作。
例如,MERGE可用于指定图形必须包含具有Person标签和特定name属性的节点。如果没有具有特定name属性的节点,则将创建具有该name属性的新节点。
|
出于性能原因,强烈建议在使用时在标签或属性上创建架构索引 |
当在完整模式上使用时MERGE,行为是整个模式匹配,或者创建整个模式。 MERGE不会部分使用现有模式。如果需要部分匹配,可以通过将模式拆分为多个MERGE子句来实现。
|
在并发更新下, |
与 类似MATCH,MERGE可以匹配某个模式的多个出现。如果有多个匹配项,则它们将全部传递到查询的后续阶段。
子句的最后一部分MERGE是ON CREATEand/orON MATCH运算符。这些运算符允许查询表达对节点或关系属性的其他更改,具体取决于元素是否MATCH在数据库中匹配 ( ) 或是否已创建 ( CREATE)。
示例图
下图用于以下示例:

要重新创建图表,请在空的 Neo4j 数据库中运行以下查询:
CREATE
(charlie:Person {name: 'Charlie Sheen', bornIn: 'New York', chauffeurName: 'John Brown'}),
(martin:Person {name: 'Martin Sheen', bornIn: 'Ohio', chauffeurName: 'Bob Brown'}),
(michael:Person {name: 'Michael Douglas', bornIn: 'New Jersey', chauffeurName: 'John Brown'}),
(oliver:Person {name: 'Oliver Stone', bornIn: 'New York', chauffeurName: 'Bill White'}),
(rob:Person {name: 'Rob Reiner', bornIn: 'New York', chauffeurName: 'Ted Green'}),
(wallStreet:Movie {title: 'Wall Street'}),
(theAmericanPresident:Movie {title: 'The American President'}),
(charlie)-[:ACTED_IN]->(wallStreet),
(martin)-[:ACTED_IN]->(wallStreet),
(michael)-[:ACTED_IN]->(wallStreet),
(martin)-[:ACTED_IN]->(theAmericanPresident),
(michael)-[:ACTED_IN]->(theAmericanPresident),
(oliver)-[:DIRECTED]->(wallStreet),
(rob)-[:DIRECTED]->(theAmericanPresident)
合并节点
合并带有标签的单个节点
合并具有特定标签的节点:
MERGE (robert:Critic)
RETURN labels(robert)

Critic由于数据库中没有标记的节点,因此会创建一个新节点:
| labels(robert) |
|---|
| ["Critic"] |
合并具有多个标签的单个节点
多个标签以冒号分隔:
MERGE (robert:Critic:Viewer)
RETURN labels(robert)
由于数据库中没有标记为和的节点,因此会创建一个新节点Critic:Viewer
| labels(robert) |
|---|
| ["Critic","Viewer"] |
从 Neo4j 5.18 开始,多个标签也可以用 & 符号分隔&,方式与标签表达式中的用法相同。 冒号:和 & 符号分隔&不能在同一个子句中混合使用。
MERGE (robert:Critic&Viewer)
RETURN labels(robert)
没有创建新节点,因为数据库中已经有一个标记为Critic和的节点:Viewer
| 标签(罗伯特) |
|---|
| [“评论家”、“观众”] |
合并具有属性的单个节点
合并与图中现有节点的属性不同的节点将创建一个新节点:
MERGE (charlie {name: 'Charlie Sheen', age: 10})
RETURN charlie
Charlie Sheen由于并非所有属性都与预先存在的节点设置的属性匹配,因此将创建一个具有名称的新节点Charlie Sheen:
| 查理 |
|---|
|
|
|
询问
|
合并指定标签和属性的单个节点
合并与现有节点匹配的标签和属性的单个节点不会创建新节点:
MERGE (michael:Person {name: 'Michael Douglas'})
RETURN michael.name, michael.bornIn
Michael Douglas匹配并返回name和属性:bornIn
| 迈克尔.姓名 | 迈克尔·伯恩 |
|---|---|
|
|
|
合并从现有节点属性派生的单个节点
可以使用现有节点属性来合并节点:
MATCH (person:Person)
MERGE (location:Location {name: person.bornIn})
RETURN person.name, person.bornIn, location
在上面的查询中,Location创建了三个带标签的节点,每个节点分别包含一个name属性,其值为New York、Ohio和New Jersey。请注意,尽管该MATCH子句导致三个绑定节点都具有New York该属性的值,但只创建了bornIn一个New York节点(即Location名称为 的节点)。由于该节点与第一个绑定节点不匹配,因此会创建该节点。但是,新创建的节点与第二个和第三个绑定节点匹配并绑定。New YorkNew YorkNew York
| 人名 | 人出生 | 地点 |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
使用ON CREATE和ON MATCH
合并ON CREATE
如果需要创建节点,则合并节点并设置属性:
MERGE (keanu:Person {name: 'Keanu Reeves', bornIn: 'Beirut', chauffeurName: 'Eric Brown'})
ON CREATE
SET keanu.created = timestamp()
RETURN keanu.name, keanu.created
该查询创建Person名为 的节点Keanu Reeves,并将bornIn属性设置为Beirut,将chauffeurName属性设置为Eric Brown。它还为属性设置了时间戳created。
| 基努.name | 基努·库欣 |
|---|---|
|
|
|
合并ON MATCH
合并节点并设置找到的节点的属性:
MERGE (person:Person)
ON MATCH
SET person.found = true
RETURN person.name, person.found
查询找到所有Person节点,在其上设置属性,并返回它们:
| 人名 | 人名.找到 |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
合并ON CREATE和ON MATCH
MERGE (person:Person)
ON MATCH
SET person.found = true
RETURN person.name, person.found
由于Person命名的节点Keanu Reeves已经存在,因此此查询不会创建新节点。相反,它会在属性上添加时间戳lastSeen。
| 基努.name | 基努·库欣 | 基努·里维斯 |
|---|---|---|
|
|
|
|
合并ON MATCH设置多个属性
如果需要设置多个属性,请用逗号分隔:
MERGE (person:Person)
ON MATCH
SET
person.found = true,
person.lastAccessed = timestamp()
RETURN person.name, person.found, person.lastAccessed
| 人名 | 人名.找到 | 人员最后访问时间 |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
合并关系
合并关系
MERGE可用于匹配或创建关系:
MATCH
(charlie:Person {name: 'Charlie Sheen'}),
(wallStreet:Movie {title: 'Wall Street'})
MERGE (charlie)-[r:ACTED_IN]->(wallStreet)
RETURN charlie.name, type(r), wallStreet.title
Charlie Sheen已标记为在 中代理Wall Street,因此找到并返回现有关系。请注意,为了在使用 时匹配或创建关系,必须指定至少一个绑定节点,这通过上例中的子句MERGE完成。MATCH
| charlie.name | 类型(r) | wallStreet.title |
|---|---|---|
|
|
|
|
|
询问
|
|
从 Neo4j 5.20 开始,通过引用同一子句中另一个实体的属性来指定实体(节点或关系)的属性的做法 例如,
询问
|
合并多个关系
MATCH
(oliver:Person {name: 'Oliver Stone'}),
(reiner:Person {name: 'Rob Reiner'})
MERGE (oliver)-[:DIRECTED]->(movie:Movie)<-[:DIRECTED]-(reiner)
RETURN movie
在示例图中,Oliver Stone和Rob Reiner从未一起工作过。当尝试在它们之间创建MERGE一个Movie节点时,Neo4j 不会使用任何Movie已连接到任一方的现有节点。而是Movie创建一个新节点。
| 电影 |
|---|
|
|
在无向关系上进行合并
MERGE也可以不指定关系的方向而使用。Cypher®将首先尝试在两个方向上匹配关系。如果任一方向上都不存在关系,它将创建一个从左到右的关系。
MATCH
(charlie:Person {name: 'Charlie Sheen'}),
(oliver:Person {name: 'Oliver Stone'})
MERGE (charlie)-[r:KNOWS]-(oliver)
RETURN r
由于示例图中Charlie Sheen和Oliver Stone彼此不认识,此MERGE查询将创建KNOWS它们之间的关系。创建的关系的方向是从左到右。
| r |
|---|
|
|
合并两个现有节点之间的关系
MERGEMATCH可以与前面的and子句结合使用,在两个绑定节点和MERGE之间建立关系,其中由返回并且由先前的创建或匹配。mnmMATCHnMERGE
MATCH (person:Person)
MERGE (location:Location {name: person.bornIn})
MERGE (person)-[r:BORN_IN]->(location)
RETURN person.name, person.bornIn, location
这是基于合并从现有节点属性派生的单个节点的示例。第二个MERGE创建了BORN_IN每个人与对应于该人bornIn属性值的位置之间的关系。 Charlie Sheen、Rob Reiner和都与同一Oliver Stone节点有关系()。BORN_IN LocationNew York
| 人名 | 人出生 | 地点 |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
合并现有节点与从节点属性派生的合并节点之间的关系
MERGE可用于同时创建新节点以及绑定节点与n之间的关系:mn
MATCH (person:Person)
MERGE (person)-[r:HAS_CHAUFFEUR]->(chauffeur:Chauffeur {name: person.chauffeurName})
RETURN person.name, person.chauffeurName, chauffeur
由于MERGE未找到匹配项 — — 在示例图中,没有标记为 的节点Chauffeur也没有HAS_CHAUFFEUR关系 — — MERGE会创建六个标记为 的节点Chauffeur,每个节点都包含一个name属性,其值对应于每个匹配Person节点的chauffeurName属性值。 还会在每个节点和新创建的对应节点之间MERGE创建关系。由于和都有一位同名的司机 — — 每种情况下都会创建一个新节点,从而产生两个具有 的节点,正确地表示了尽管属性可能相同,但这却是两个不同的人。这与上面在合并两个现有节点之间的关系中显示的示例形成了对比,其中第一个用于绑定节点并防止在第二个上重新创建(从而重复)它们。HAS_CHAUFFEURPersonChauffeur'Charlie Sheen''Michael Douglas''John Brown' Chauffeurname'John Brown'nameMERGELocationMERGE
| 人名 | 人员.司机姓名 | 司机 |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
使用节点属性唯一性约束MERGE
Cypher 可防止MERGE在使用涉及属性唯一性约束的模式时产生冲突的结果。在这种情况下,最多只能有一个节点与该模式匹配。
例如,给定两个属性节点唯一性约束:Person(id)和,如果有两个不同的节点(一个具有12,另一个具有437),或者只有一个节点仅具有其中一个属性:Person(ssn),则查询将失败。换句话说,必须只有一个节点与模式匹配,否则没有匹配的节点。MERGE (n:Person {id: 12, ssn: 437})idssn
请注意,以下示例假定存在使用以下命令创建的属性唯一性约束:
CREATE CONSTRAINT FOR (n:Person) REQUIRE n.name IS UNIQUE;
CREATE CONSTRAINT FOR (n:Person) REQUIRE n.role IS UNIQUE;
如果未找到节点,则使用属性唯一性约束合并节点会创建一个新节点
name鉴于所有节点的属性都具有节点属性唯一性约束Person,以下查询将创建一个具有属性的新Person节点。如果节点已经存在,则将匹配现有节点。nameLaurence FishburneLaurence FishburneMERGE
CREATE CONSTRAINT FOR (n:Person) REQUIRE n.name IS UNIQUE;
CREATE CONSTRAINT FOR (n:Person) REQUIRE n.role IS UNIQUE;
| 劳伦斯·纳姆 |
|---|
|
|
使用节点属性唯一性约束进行合并匹配现有节点
name鉴于所有节点的属性的属性唯一性约束Person,以下查询将匹配具有属性的预先存在的Person节点。nameOliver Stone
MERGE (oliver:Person {name: 'Oliver Stone'})
RETURN oliver.name, oliver.bornIn
| oliver.name | 奥利弗·伯恩 |
|---|---|
|
|
|
与属性唯一性约束和部分匹配合并
当找到部分匹配时,使用属性唯一性约束进行合并失败:
MERGE (michael:Person {name: 'Michael Douglas', role: 'Gordon Gekko'})
RETURN michael
虽然存在Person名为 的匹配唯一节点Michael Douglas,但没有角色为 的唯一节点,Gordon Gekko因此MERGE匹配失败。
节点已存在,标签为“Person”,属性为“name”=“Michael Douglas”
要将 设置为role,请改用以下子句:Gordon GekkoMichael DouglasSET
MERGE (michael:Person {name: 'Michael Douglas'})
SET michael.role = 'Gordon Gekko'
设置 1 个属性
与属性唯一性约束和冲突匹配进行合并
当发现冲突的匹配时,使用属性唯一性约束进行合并会失败:
MERGE (michael:Person {name: 'Michael Douglas'})
SET michael.role = 'Gordon Gekko'
虽然有一个Person名为 的匹配唯一节点Oliver Stone,但还有另一个Person角色为 的唯一节点Gordon Gekko,因此MERGE匹配失败。
节点已存在,标签为“Person”,属性为“name”=“Oliver Stone”
使用关系属性唯一性约束MERGE
上面关于节点唯一性约束的所有内容也适用于关系唯一性约束。但是,对于关系唯一性约束,还有一些其他事项需要考虑。
例如,如果存在关系唯一性约束()-[:ACTED_IN(year)]-(),则以下查询(其中并非所有模式节点都绑定)将会失败:
MERGE (charlie:Person {name: 'Charlie Sheen'})-[r:ACTED_IN {year: 1987}]->(wallStreet:Movie {title: 'Wall Street'})
RETURN charlie.name, type(r), wallStreet.title
这是由于 的全有或全无语义MERGE,如果存在与给定year属性的关系但没有完整模式的匹配,则会导致查询失败。在此示例中,由于未找到与 的匹配项,MERGE将尝试创建包含与 的关系的完整模式{year: 1987},这将导致约束违反错误。
因此,建议(尤其是当存在关系唯一性约束时)始终在模式中使用绑定节点MERGE。因此,以下将是更合适的查询组合:
MATCH
(charlie:Person {name: 'Charlie Sheen'}),
(wallStreet:Movie {title: 'Wall Street'})
MERGE (charlie)-[r:ACTED_IN {year: 1987}]->(wallStreet)
RETURN charlie.name, type(r), wallStreet.title
使用地图参数MERGE
MERGE不支持与 相同的映射参数CREATE。要将映射参数与 一起使用MERGE,必须明确使用预期属性,例如以下示例。有关参数的更多信息,请参阅参数。
{
"param": {
"name": "Keanu Reeves",
"bornIn": "Beirut",
"chauffeurName": "Eric Brown"
}
}
MERGE (person:Person {name: $param.name, bornIn: $param.bornIn, chauffeurName: $param.chauffeurName})
RETURN person.name, person.bornIn, person.chauffeurName
| 人名 | 人出生 | 人员.司机姓名 |
|---|---|---|
|
|
|
|
7480



被折叠的 条评论
为什么被折叠?



