更新数据 #
一、更新概述 #
1.1 更新类型 #
text
更新类型:
├── 属性更新:修改顶点或边的属性
├── 标签更新:添加或移除标签
├── 边更新:修改边的属性
└── 批量更新:批量修改数据
1.2 更新方式 #
text
更新方式:
├── Gremlin:property(), sideEffect
└── SPARQL:DELETE/INSERT
二、Gremlin属性更新 #
2.1 基本属性更新 #
gremlin
// 更新单个属性
g.V('1').property('age', 31)
// 更新多个属性
g.V('1').
property('age', 31).
property('email', 'new@example.com').
property('status', 'active')
// 更新并返回
g.V('1').property('age', 31).valueMap()
2.2 条件更新 #
gremlin
// 条件更新
g.V('1').has('age', 30).property('age', 31)
// 使用filter
g.V('1').filter(has('status', 'active')).property('status', 'inactive')
// 使用where
g.V().where(has('status', 'active').has('lastLogin', lt(someDate))).
property('status', 'inactive')
2.3 增量更新 #
gremlin
// 数值增量
g.V('1').property('age', values('age').math('_ + 1'))
// 使用sack
g.V('1').sack(assign).by('age').
sack(math('_ + 1')).
property('age', sack())
// 更新计数器
g.V('1').property('viewCount', values('viewCount').math('_ + 1'))
2.4 多值属性更新 #
gremlin
// 添加到列表
g.V('1').property(list, 'tags', 'newTag')
// 添加到集合
g.V('1').property(set, 'tags', 'newTag')
// 删除列表中的值
g.V('1').properties('tags').hasValue('oldTag').drop()
// 替换所有值
g.V('1').properties('tags').drop()
g.V('1').property(list, 'tags', 'tag1').property(list, 'tags', 'tag2')
2.5 使用Map更新 #
gremlin
// 使用Map更新
g.V('1').property(map, [
'name': 'Tom',
'age': 31,
'email': 'new@example.com'
])
// 合并更新
g.V('1').property('name', 'Tom').property('age', 31)
三、Gremlin边属性更新 #
3.1 基本更新 #
gremlin
// 更新边属性
g.E('e1').property('weight', 0.9)
// 更新多个属性
g.E('e1').
property('weight', 0.9).
property('since', 2021)
// 条件更新
g.E('e1').has('weight', lt(0.5)).property('weight', 0.5)
3.2 批量更新边 #
gremlin
// 批量更新
g.E().hasLabel('knows').property('verified', true)
// 条件批量更新
g.E().has('weight', lt(0.5)).
property('weight', 0.5).
property('updatedAt', datetime())
四、SPARQL更新 #
4.1 DELETE/INSERT #
sparql
PREFIX ex: <http://example.org/>
DELETE {
ex:Tom ex:age ?oldAge .
}
INSERT {
ex:Tom ex:age 31 .
}
WHERE {
ex:Tom ex:age ?oldAge .
}
4.2 条件更新 #
sparql
PREFIX ex: <http://example.org/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
DELETE {
?person ex:status ?oldStatus .
}
INSERT {
?person ex:status "inactive" .
}
WHERE {
?person ex:status ?oldStatus .
?person ex:lastLogin ?date .
FILTER (?date < "2023-01-01"^^xsd:date)
}
4.3 批量更新 #
sparql
PREFIX ex: <http://example.org/>
DELETE {
?person ex:ageGroup ?oldGroup .
}
INSERT {
?person ex:ageGroup "senior" .
}
WHERE {
?person ex:age ?age .
OPTIONAL { ?person ex:ageGroup ?oldGroup }
FILTER (?age >= 60)
}
4.4 计算更新 #
sparql
PREFIX ex: <http://example.org/>
DELETE {
?product ex:priceWithTax ?oldPrice .
}
INSERT {
?product ex:priceWithTax ?newPrice .
}
WHERE {
?product ex:price ?price .
OPTIONAL { ?product ex:priceWithTax ?oldPrice }
BIND (?price * 1.1 AS ?newPrice)
}
五、标签更新 #
5.1 添加标签 #
gremlin
// Neptune添加标签(使用~label属性)
g.V('1').property('~label', values('~label').math('_ + ":manager"'))
// 或重新设置
g.V('1').property('~label', 'person:employee:manager')
5.2 移除标签 #
gremlin
// Neptune不支持直接移除标签
// 需要重新设置标签
g.V('1').property('~label', 'person:employee')
六、批量更新 #
6.1 Gremlin批量更新 #
gremlin
// 批量更新属性
g.V().hasLabel('person').
has('status', 'active').
property('verified', true)
// 批量条件更新
g.V().hasLabel('user').
has('lastLogin', lt(someDate)).
property('status', 'inactive').
property('updatedAt', datetime())
// 使用inject批量更新
g.inject(['user_001', 'user_002', 'user_003']).unfold().
addV('user').property('userId', identity).
property('status', 'active')
6.2 SPARQL批量更新 #
sparql
PREFIX ex: <http://example.org/>
DELETE {
?person ex:status ?oldStatus .
}
INSERT {
?person ex:status "inactive" .
?person ex:updatedAt "2024-01-01"^^xsd:date .
}
WHERE {
?person a ex:Person .
?person ex:status ?oldStatus .
?person ex:lastLogin ?date .
FILTER (?date < "2023-01-01"^^xsd:date)
}
七、MERGE操作 #
7.1 Gremlin MERGE #
gremlin
// MERGE顶点
g.V().hasLabel('person').has('userId', 'user_001').
fold().
coalesce(
unfold(),
addV('person').property('userId', 'user_001')
).
property('name', 'Tom').
property('updatedAt', datetime())
// MERGE属性
g.V('1').as('v').
coalesce(
properties('nickname'),
property('nickname', values('name'))
)
7.2 SPARQL MERGE #
sparql
PREFIX ex: <http://example.org/>
INSERT {
ex:Tom ex:name "Tom" .
ex:Tom ex:updatedAt "2024-01-01"^^xsd:date .
}
WHERE {
OPTIONAL { ex:Tom ex:name ?oldName }
}
八、实际应用示例 #
8.1 用户状态更新 #
gremlin
// 更新用户状态
g.V().has('userId', 'user_001').
property('status', 'inactive').
property('updatedAt', datetime()).
property('statusChangedAt', datetime())
// 批量更新过期用户
g.V().hasLabel('user').
has('lastLogin', lt(thirtyDaysAgo)).
has('status', 'active').
property('status', 'inactive').
property('updatedAt', datetime())
8.2 产品库存更新 #
gremlin
// 减少库存
g.V().has('productId', 'prod_001').
property('stock', values('stock').math('_ - 1'))
// 条件更新库存
g.V().has('productId', 'prod_001').
has('stock', gt(0)).
property('stock', values('stock').math('_ - 1'))
// 批量更新价格
g.V().hasLabel('product').
has('category', 'Electronics').
property('price', values('price').math('_ * 0.9')) // 9折
8.3 关系更新 #
gremlin
// 更新关系权重
g.V().has('userId', 'user_001').outE('follows').as('e').
inV().has('userId', 'user_002').
select('e').
property('weight', values('weight').math('_ + 0.1'))
// 添加关系属性
g.V().has('userId', 'user_001').outE('follows').
has('verified', false).
property('verified', true).
property('verifiedAt', datetime())
8.4 计数器更新 #
gremlin
// 增加浏览次数
g.V().has('productId', 'prod_001').
property('viewCount', coalesce(values('viewCount'), constant(0)).math('_ + 1'))
// 增加点赞数
g.V().has('postId', 'post_001').
property('likeCount', values('likeCount').math('_ + 1'))
九、事务处理 #
9.1 Neptune事务 #
text
Neptune事务特性:
├── 自动提交
├── 支持事务
├── 快照隔离
└── ACID保证
9.2 批量事务 #
python
# Python批量更新
from gremlin_python.driver.driver_remote_connection import DriverRemoteConnection
from gremlin_python.process.anonymous_traversal import traversal
connection = DriverRemoteConnection('wss://endpoint:8182/gremlin', 'g')
g = traversal().withRemote(connection)
# 批量更新
for user_id in user_ids:
g.V().has('userId', user_id).property('status', 'active').iterate()
connection.close()
十、最佳实践 #
10.1 性能优化 #
text
性能优化建议:
├── 批量更新优于单条更新
├── 使用条件减少扫描范围
├── 合理使用索引
├── 避免全图更新
└── 控制事务大小
10.2 数据一致性 #
text
数据一致性建议:
├── 使用MERGE处理重复
├── 添加时间戳记录更新
├── 使用条件更新避免冲突
├── 记录更新历史
└── 验证数据完整性
十一、总结 #
更新数据要点:
| 操作 | Gremlin | SPARQL |
|---|---|---|
| 属性更新 | property() | DELETE/INSERT |
| 条件更新 | has().property() | FILTER |
| 增量更新 | math() | BIND |
| 批量更新 | iterate() | 多三元组 |
| MERGE | coalesce() | INSERT WHERE |
下一步,让我们学习删除数据!
最后更新:2026-03-27