更新数据 #

一、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 删除标签

最佳实践:

  1. 使用索引加速更新
  2. 使用+=批量更新
  3. 使用MERGE处理更新或创建
  4. 批量更新使用UNWIND
  5. 更新后验证返回结果

下一步,让我们学习删除数据!

最后更新:2026-03-27