更新数据 #

一、更新概述 #

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