更新数据 #
一、SET语句概述 #
1.1 基本语法 #
cypher
SET property = value
SET property += {key: value}
SET node:Label
1.2 SET特点 #
text
SET特点:
├── 更新节点属性
├── 更新关系属性
├── 添加节点标签
├── 创建新属性
└── 删除属性(设为NULL)
二、更新属性 #
2.1 更新单个属性 #
cypher
MATCH (p:Person {name: 'Tom'})
SET p.age = 31
RETURN p
2.2 更新多个属性 #
cypher
MATCH (p:Person {name: 'Tom'})
SET p.age = 31, p.city = 'New York'
RETURN p
2.3 使用+=更新属性 #
cypher
MATCH (p:Person {name: 'Tom'})
SET p += {age: 31, city: 'New York', country: 'USA'}
RETURN p
2.4 替换所有属性 #
cypher
MATCH (p:Person {name: 'Tom'})
SET p = {name: 'Tom', age: 31, city: 'New York'}
RETURN p
2.5 使用参数更新 #
cypher
:param props => {age: 31, city: 'New York'}
MATCH (p:Person {name: 'Tom'})
SET p += $props
RETURN p
2.6 条件更新 #
cypher
MATCH (p:Person)
WHERE p.age > 60
SET p.status = 'senior'
RETURN p
2.7 批量更新 #
cypher
MATCH (p:Person)
WHERE p.age > 18
SET p.isAdult = true
2.8 使用UNWIND批量更新 #
cypher
:param updates => [
{name: 'Tom', age: 31},
{name: 'Jerry', age: 26},
{name: 'Mike', age: 36}
]
UNWIND $updates AS update
MATCH (p:Person {name: update.name})
SET p.age = update.age
三、创建和删除属性 #
3.1 创建新属性 #
cypher
MATCH (p:Person {name: 'Tom'})
SET p.email = 'tom@example.com'
3.2 删除属性(设为NULL) #
cypher
MATCH (p:Person {name: 'Tom'})
SET p.email = NULL
3.3 使用REMOVE删除属性 #
cypher
MATCH (p:Person {name: 'Tom'})
REMOVE p.email
3.4 条件删除属性 #
cypher
MATCH (p:Person)
WHERE p.tempData IS NOT NULL
REMOVE p.tempData
四、更新标签 #
4.1 添加标签 #
cypher
MATCH (p:Person {name: 'Tom'})
SET p:Actor
RETURN p
4.2 添加多个标签 #
cypher
MATCH (p:Person {name: 'Tom'})
SET p:Actor:Director:Producer
RETURN p
4.3 条件添加标签 #
cypher
MATCH (p:Person)
WHERE p.occupation = 'Actor'
SET p:Actor
4.4 删除标签 #
cypher
MATCH (p:Person {name: 'Tom'})
REMOVE p:Actor
五、更新关系属性 #
5.1 更新关系属性 #
cypher
MATCH (a)-[r:KNOWS]->(b)
WHERE a.name = 'Tom' AND b.name = 'Jerry'
SET r.level = 'best_friend'
RETURN r
5.2 更新多个关系属性 #
cypher
MATCH (a)-[r:KNOWS]->(b)
WHERE a.name = 'Tom' AND b.name = 'Jerry'
SET r.level = 'best_friend', r.since = 2020
5.3 使用+=更新关系属性 #
cypher
MATCH (a)-[r:KNOWS]->(b)
WHERE a.name = 'Tom' AND b.name = 'Jerry'
SET r += {level: 'best_friend', updated: timestamp()}
5.4 批量更新关系属性 #
cypher
MATCH ()-[r:KNOWS]->()
SET r.verified = true
六、MERGE更新 #
6.1 MERGE更新概述 #
cypher
MERGE (p:Person {name: 'Tom'})
ON CREATE SET p.created = timestamp()
ON MATCH SET p.updated = timestamp()
RETURN p
6.2 ON CREATE #
cypher
MERGE (p:Person {id: 'person_001'})
ON CREATE SET
p.name = 'Tom',
p.age = 30,
p.created = timestamp()
RETURN p
6.3 ON MATCH #
cypher
MERGE (p:Person {id: 'person_001'})
ON MATCH SET
p.lastSeen = timestamp(),
p.visitCount = coalesce(p.visitCount, 0) + 1
RETURN p
6.4 完整MERGE示例 #
cypher
MERGE (p:Person {id: 'person_001'})
ON CREATE SET
p.name = 'Tom',
p.age = 30,
p.created = timestamp()
ON MATCH SET
p.name = 'Tom',
p.age = 31,
p.updated = timestamp()
RETURN p
6.5 MERGE关系 #
cypher
MATCH (a:Person {name: 'Tom'})
MATCH (b:Person {name: 'Jerry'})
MERGE (a)-[r:KNOWS]->(b)
ON CREATE SET r.since = 2020
ON MATCH SET r.lastSeen = timestamp()
七、FOREACH更新 #
7.1 FOREACH基本用法 #
cypher
MATCH (p:Person {name: 'Tom'})
FOREACH (x IN CASE WHEN p.age > 30 THEN [1] ELSE [] END |
SET p.status = 'senior'
)
7.2 条件更新 #
cypher
MATCH (p:Person)
FOREACH (_ IN CASE WHEN p.age >= 18 AND p.age < 60 THEN [1] ELSE [] END |
SET p.ageGroup = 'adult'
)
FOREACH (_ IN CASE WHEN p.age >= 60 THEN [1] ELSE [] END |
SET p.ageGroup = 'senior'
)
7.3 批量更新列表属性 #
cypher
MATCH (p:Person {name: 'Tom'})
SET p.tags = []
FOREACH (tag IN ['developer', 'designer', 'manager'] |
SET p.tags = p.tags + tag
)
八、CASE表达式更新 #
8.1 条件更新属性 #
cypher
MATCH (p:Person)
SET p.ageGroup = CASE
WHEN p.age < 18 THEN 'minor'
WHEN p.age < 60 THEN 'adult'
ELSE 'senior'
END
RETURN p
8.2 多条件更新 #
cypher
MATCH (p:Person)
SET p.status = CASE p.status
WHEN 'active' THEN 'enabled'
WHEN 'inactive' THEN 'disabled'
ELSE 'unknown'
END
九、WITH子句更新 #
9.1 使用WITH中间处理 #
cypher
MATCH (p:Person)
WITH p, p.age * 2 AS doubleAge
SET p.doubleAge = doubleAge
RETURN p
9.2 聚合后更新 #
cypher
MATCH (p:Person)-[:KNOWS]->(f:Person)
WITH p, count(f) AS friendCount
SET p.friendCount = friendCount
RETURN p.name, p.friendCount
9.3 排序后更新 #
cypher
MATCH (p:Person)
WITH p ORDER BY p.age DESC
SET p.rank = id(p)
RETURN p.name, p.rank
十、批量更新优化 #
10.1 使用CALL分批处理 #
cypher
MATCH (p:Person)
CALL {
WITH p
SET p.updated = timestamp()
} IN TRANSACTIONS OF 1000 ROWS
10.2 使用UNWIND批量更新 #
cypher
:param updates => [
{id: 1, name: 'Tom', age: 31},
{id: 2, name: 'Jerry', age: 26},
{id: 3, name: 'Mike', age: 36}
]
UNWIND $updates AS update
MATCH (p:Person {id: update.id})
SET p.name = update.name, p.age = update.age
10.3 批量更新性能建议 #
text
建议:
├── 使用参数批量更新
├── 分批处理大量数据
├── 避免单条更新循环
├── 使用索引加速查找
└── 考虑事务大小
十一、更新函数 #
11.1 使用函数更新 #
cypher
MATCH (p:Person)
SET p.name = toUpper(p.name)
RETURN p
11.2 使用时间函数 #
cypher
MATCH (p:Person {name: 'Tom'})
SET p.updatedAt = datetime()
RETURN p
11.3 使用数学函数 #
cypher
MATCH (p:Person)
SET p.age = p.age + 1
RETURN p
11.4 使用coalesce #
cypher
MATCH (p:Person)
SET p.displayName = coalesce(p.nickname, p.name, 'Unknown')
RETURN p
十二、原子更新 #
12.1 原子计数器 #
cypher
MATCH (p:Person {id: 'person_001'})
SET p.viewCount = coalesce(p.viewCount, 0) + 1
RETURN p.viewCount
12.2 原子状态更新 #
cypher
MATCH (p:Person {id: 'person_001', status: 'pending'})
SET p.status = 'processed'
RETURN p
12.3 条件竞争更新 #
cypher
MATCH (p:Person {id: 'person_001'})
WHERE p.version = $expectedVersion
SET p.version = p.version + 1, p.data = $newData
RETURN p
十三、更新最佳实践 #
13.1 使用索引 #
cypher
CREATE INDEX FOR (p:Person) ON (p.id)
MATCH (p:Person {id: 'person_001'})
SET p.name = 'Tom'
13.2 时间戳管理 #
cypher
MATCH (p:Person {id: 'person_001'})
SET p.name = 'Tom', p.updatedAt = datetime()
13.3 版本控制 #
cypher
MERGE (p:Person {id: 'person_001'})
ON CREATE SET p.version = 1, p.created = timestamp()
ON MATCH SET p.version = p.version + 1, p.updated = timestamp()
13.4 避免反模式 #
text
避免:
├── 不使用索引的更新
├── 大量单条更新
├── 更新时忽略NULL处理
├── 不必要的大批量更新
└── 更新后不验证结果
十四、实际应用示例 #
14.1 更新用户信息 #
cypher
MATCH (u:User {id: 'user_001'})
SET u += {
firstName: 'Tom',
lastName: 'Hanks',
email: 'tom@example.com',
updatedAt: datetime()
}
RETURN u
14.2 更新订单状态 #
cypher
MATCH (o:Order {id: 'order_001'})
SET o.status = 'shipped', o.shippedAt = datetime()
RETURN o
14.3 更新产品库存 #
cypher
MATCH (p:Product {id: 'prod_001'})
SET p.stock = p.stock - 1, p.updatedAt = datetime()
RETURN p
14.4 更新社交关系 #
cypher
MATCH (a:User {id: 'user_001'})-[r:FOLLOWS]->(b:User {id: 'user_002'})
SET r.status = 'active', r.updatedAt = datetime()
RETURN r
14.5 批量更新状态 #
cypher
MATCH (o:Order)
WHERE o.status = 'pending' AND o.createdAt < datetime() - duration('P7D')
SET o.status = 'expired', o.expiredAt = datetime()
RETURN o
十五、总结 #
更新数据要点:
| 操作 | 语法 | 说明 |
|---|---|---|
| 更新属性 | SET n.prop = value | 更新单个属性 |
| 批量更新 | SET n += | 批量更新属性 |
| 替换属性 | SET n = | 替换所有属性 |
| 删除属性 | SET n.prop = NULL | 删除属性 |
| 添加标签 | SET n:Label | 添加标签 |
| 删除标签 | REMOVE n:Label | 删除标签 |
最佳实践:
- 使用索引加速更新
- 使用+=批量更新
- 使用MERGE处理更新或创建
- 批量更新使用UNWIND
- 更新后验证返回结果
下一步,让我们学习删除数据!
最后更新:2026-03-27