保留文档版本历史记录
当数据发生更改时,某些应用程序会要求保留旧版本的数据。 在文档版本控制模式中,较旧的数据版本保留在与当前数据不同的单独集合中。
文档版本控制模式可让您将当前文档及其历史记录保存在同一数据库中,避免使用多个系统来管理数据历史记录。
关于此任务
如果您的数据满足以下条件,则文档版本控制模式效果最佳:
文档很少更新。
需要版本跟踪的文档很少。
当前数据和历史数据一般是分开查询的。 在文档版本控制模式中,历史数据与当前数据存储在单独的集合中,因此在同一操作中返回两者的成本可能很高。
如果前面的条件不适合您的使用案例,请考虑其他解决方案或更改文档版本控制模式的实现方式。
开始之前
在以下示例中,一家公司使用文档版本控制模式来追踪客户保单的更改。 将示例文档插入到 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 } ]