文档菜单
文档首页
/
MongoDB 手册
/ / /

保留文档版本历史记录

本页内容

  • 关于此任务
  • 开始之前
  • 步骤
  • 下一步
  • 了解更多

当您的数据发生变化时,某些应用程序需要保留旧版本的数据可用。在 文档版本控制模式 中,旧数据版本与当前数据分开保存在单独的集合中。

文档版本控制模式允许您将当前文档及其历史记录保存在同一个数据库中,避免需要使用多个系统来管理数据历史。

如果您的数据满足以下标准,则文档版本控制模式效果最佳

  • 文档更新频率不高。

  • 需要版本跟踪的文档数量很少。

  • 当前数据和历史数据通常分别查询。在文档版本控制模式中,历史数据存储在单独的集合中,与当前数据分开,因此在同一操作中返回两者可能代价高昂。

如果上述标准不符合您的用例,请考虑不同的解决方案或更改实施文档版本控制模式的方式。

以下示例中,一家保险公司使用文档版本控制模式来跟踪客户政策的变更。将示例文档插入currentPoliciespolicyRevisions 集合

db.currentPolicies.insertOne(
{
policyId: 1,
customerName: "Michelle",
revision: 1,
itemsInsured: [
"golf clubs",
"car"
],
dateSet: new Date()
}
)
db.policyRevisions.insertOne(
{
policyId: 1,
customerName: "Michelle",
revision: 1,
itemsInsured: [
"golf clubs",
"car"
],
dateSet: new Date()
}
)

使用文档版本控制模式,当政策更新时,会发生以下写入操作

  • 政策在 currentPolicies 集合中更新。该 currentPolicies 集合只包含每个 policyId 的当前数据修订版本。

  • 原始政策被写入 policyRevisions 集合以记录政策变更。

例如,如果用户 Michelle 想要为她政策添加一个监控,应用程序将运行以下操作

1
db.currentPolicies.updateOne(
{ policyId: 1 },
{
$push: {
itemsInsured: "watch"
},
$inc: {
revision: 1
},
$currentDate: {
dateSet: true
}
}
)

更新后的文档

{
_id: ObjectId("661e873d1a930b8ea1f75c57"),
policyId: 1,
customerName: 'Michelle',
revision: 2,
itemsInsured: [ 'golf clubs', 'car', 'watch' ],
dateSet: ISODate("2024-04-16T14:12:24.476Z")
}
2
db.currentPolicies.aggregate( [
{
$match: { policyId: 1 }
},
{
$set: { _id: new ObjectId() }
},
{
$merge: {
into: { db: "test", coll: "policyRevisions" },
on: "_id",
whenNotMatched: "insert"
}
}
] )

在运行上述聚合操作后,policyRevisions 集合将包含原始和更新后的政策

[
{
_id: ObjectId("6626c8f02a98aba8ddec31d1"),
policyId: 1,
customerName: 'Michelle',
revision: 1,
itemsInsured: [ 'golf clubs', 'car' ],
dateSet: ISODate("2024-04-22T20:30:40.809Z")
},
{
_id: ObjectId("6626c92b2a98aba8ddec31d2"),
customerName: 'Michelle',
dateSet: ISODate("2024-04-22T20:31:03.000Z"),
itemsInsured: [ 'golf clubs', 'car', 'watch' ],
policyId: 1,
revision: 2
}
]

要查看客户的保单历史,您可以按修订排序 policyRevisions 集合。考虑如果客户Michelle对其保单进行了另一项更改,并且不再想为她的高尔夫球杆投保。

1
db.currentPolicies.updateOne(
{ policyId: 1 },
{
$pull: {
itemsInsured: "golf clubs"
},
$inc: {
revision: 1
},
$currentDate: {
dateSet: true
}
}
)

更新后的文档

{
_id: ObjectId("661e873d1a930b8ea1f75c57"),
policyId: 1,
customerName: 'Michelle',
revision: 3,
itemsInsured: [ 'car', 'watch' ],
dateSet: ISODate("2024-04-16T14:13:38.203Z")
}
2
db.currentPolicies.aggregate( [
{
$match: { policyId: 1 }
},
{
$set: { _id: new ObjectId() }
},
{
$merge: {
into: { db: "test", coll: "policyRevisions" },
on: "_id",
whenNotMatched: "insert"
}
}
] )
3
db.policyRevisions.find( { policyId: 1 } ).sort( { revision: 1 } )

输出

[
{
_id: ObjectId("6626c8f02a98aba8ddec31d1"),
policyId: 1,
customerName: 'Michelle',
revision: 1,
itemsInsured: [ 'golf clubs', 'car' ],
dateSet: ISODate("2024-04-22T20:30:40.809Z")
},
{
_id: ObjectId("6626c92b2a98aba8ddec31d2"),
customerName: 'Michelle',
dateSet: ISODate("2024-04-22T20:31:03.000Z"),
itemsInsured: [ 'golf clubs', 'car', 'watch' ],
policyId: 1,
revision: 2
},
{
_id: ObjectId("6626c9832a98aba8ddec31d3"),
customerName: 'Michelle',
dateSet: ISODate("2024-04-22T20:32:43.232Z"),
itemsInsured: [ 'car', 'watch' ],
policyId: 1,
revision: 3
}
]
  • 维护不同的架构版本

  • 模式设计过程

  • 分组数据

后退

版本控制