保留文档版本历史记录
当您的数据发生变化时,某些应用程序需要保留旧版本的数据可用。在 文档版本控制模式 中,旧数据版本与当前数据分开保存在单独的集合中。
文档版本控制模式允许您将当前文档及其历史记录保存在同一个数据库中,避免需要使用多个系统来管理数据历史。
关于此任务
如果您的数据满足以下标准,则文档版本控制模式效果最佳
文档更新频率不高。
需要版本跟踪的文档数量很少。
当前数据和历史数据通常分别查询。在文档版本控制模式中,历史数据存储在单独的集合中,与当前数据分开,因此在同一操作中返回两者可能代价高昂。
如果上述标准不符合您的用例,请考虑不同的解决方案或更改实施文档版本控制模式的方式。
开始之前
以下示例中,一家保险公司使用文档版本控制模式来跟踪客户政策的变更。将示例文档插入currentPolicies
和 policyRevisions
集合
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
更新 currentPolicies
集合中的政策
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
将更新后的政策写入 policyRevisions
集合
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
在 currentPolicies 集合中更新保单
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
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 } ]