在 Neo4j 的早期版本中(2.x 及更早),Cypher 提供了一个特殊的语句叫做 CREATE UNIQUE
,用于在某个路径上自动创建缺失的节点或关系,以确保整个路径是唯一的。
然而,从 Neo4j 3.x 起 CREATE UNIQUE
被正式弃用,现在推荐使用更强大、更明确的 MERGE
语句替代。
一、什么是 CREATE UNIQUE
?
CREATE UNIQUE
是一种类似于 MERGE
的语句,它的语义是:
在给定的路径中,如果该路径尚未存在,就创建路径上缺失的节点和关系。
它强调的是整个路径的唯一性,而不仅仅是某个节点或某个关系的唯一性。
二、基本语法
CREATE UNIQUE (a)-[:KNOWS]->(b)
等价于:
- 如果
a
和b
都存在,并且之间不存在KNOWS
关系,则创建该关系; - 如果
a
或b
不存在,则会自动创建缺失部分,确保整条路径存在。
三、示例对比
3.1 使用 CREATE UNIQUE
MATCH (a:Person {name: 'Alice'})
CREATE UNIQUE (a)-[:FRIENDS_WITH]->(b:Person {name: 'Bob'})
RETURN a, b
- 如果
Alice
节点存在,Bob
不存在,则会自动创建Bob
并建立关系; - 如果关系已存在,不会重复创建。
3.2 使用现代写法(推荐)
等价的 MERGE
写法如下:
MATCH (a:Person {name: 'Alice'})
MERGE (a)-[:FRIENDS_WITH]->(b:Person {name: 'Bob'})
RETURN a, b
MERGE
能够以更清晰的方式定义节点、关系及其唯一性范围;- 更符合 Cypher 的现代语法风格;
- 性能更好,控制更精确。
四、为什么弃用 CREATE UNIQUE
?
-
语义不清晰:
CREATE UNIQUE
是路径级唯一,实际行为很复杂、不透明,容易造成误解。
-
效率低下:
- 查询优化器难以优化
CREATE UNIQUE
的执行路径,性能不可控。
- 查询优化器难以优化
-
不可组合:
- 不如
MERGE
灵活,无法设置ON CREATE SET
或ON MATCH SET
。
- 不如
-
已被 MERGE 完全替代:
- 使用
MERGE
可以更清楚地控制节点唯一性和关系唯一性。
- 使用
五、迁移建议(使用 MERGE
替代)
旧写法:
CREATE UNIQUE (a)-[:KNOWS]->(b:Person {name: 'Bob'})
推荐新写法:
MERGE (a)-[:KNOWS]->(b:Person {name: 'Bob'})
如果还没有 a
节点,也可以这样写:
MERGE (a:Person {name: 'Alice'})
MERGE (b:Person {name: 'Bob'})
MERGE (a)-[:KNOWS]->(b)
六、总结
项目 | CREATE UNIQUE | MERGE |
---|---|---|
是否已弃用 | 是(从 Neo4j 3.0 起) | 否(官方推荐) |
作用 | 创建整个路径(缺啥补啥) | 精确控制某个节点或关系的唯一性 |
是否推荐使用 | 否 | 是 |
替代语法 | 无 | MERGE + 可选的 ON CREATE SET 等 |
七、参考建议
- 如果正在学习 Neo4j 或编写生产代码,请不要再使用
CREATE UNIQUE
; - 所有功能都可以用
MERGE
更安全、更高效地实现; - 如果在维护旧项目中的
CREATE UNIQUE
,建议重构为MERGE
写法。