When your data changes, some applications require that older versions of your data are kept available. In the Document Versioning Pattern, older data versions are retained in a separate collection from the current data.当数据发生变化时,一些应用程序要求保留旧版本的数据。在文档版本控制模式中,旧数据版本与当前数据保留在单独的集合中。
The Document Versioning Pattern lets you keep current documents and their history in the same database, and avoid having to use multiple systems to manage data history.文档版本控制模式允许您将当前文档及其历史记录保存在同一个数据库中,并避免使用多个系统来管理数据历史记录。
About this Task关于此任务
The Document Versioning Pattern works best if your data meets these criteria:如果数据符合以下条件,文档版本控制模式最有效:
Documents are updated infrequently.文档更新不频繁。There are few documents that require version tracking.很少有文档需要版本跟踪。Current data and historical data are generally queried separately. In the Document Versioning Pattern, historical data is stored in a separate collection from the current data, so returning both in the same operation can be expensive.当前数据和历史数据通常是分开查询的。在文档版本控制模式中,历史数据与当前数据存储在单独的集合中,因此在同一操作中同时返回这两个数据可能代价高昂。
If the preceding criteria do not fit your use case, consider a different solution or change how you implement the Document Versioning Pattern.如果上述标准不符合用例,请考虑其他解决方案或更改文档版本控制模式的实现方式。
Before you Begin开始之前
In the following example, an insurance company uses the Document Versioning Pattern to track changes to customer policies. Insert the sample document into the 在下面的示例中,一家保险公司使用文档版本控制模式来跟踪客户保单的更改。将示例文档插入到currentPolicies and policyRevisions collections: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()
}
)Steps步骤
With the Document Versioning Pattern, when a policy is updated, the following writes occur:使用文档版本控制模式,当更新策略时,会发生以下写入操作:
The policy is updated in the该策略在currentPoliciescollection. ThecurrentPoliciescollection only contains the current data revision of eachpolicyId.currentPolicies集合中更新。currentPolicies集合仅包含每个policyId的当前数据修订。The original policy is written to the原始策略会写入policyRevisionscollection to keep a record of policy changes.policyRevisions集合,以记录策略更改。
For example, if the user Michelle wants to add a watch to her policy, the application runs these operations:例如,如果用户Michelle想要将手表添加到她的策略中,应用程序将运行以下操作:
Update the policy in the currentPolicies collection更新当前Policies集合中的策略
db.currentPolicies.updateOne(
{ policyId: 1 },
{
$push: {
itemsInsured: "watch"
},
$inc: {
revision: 1
},
$currentDate: {
dateSet: true
}
}
)
Updated document:更新文件:
{
_id: ObjectId("661e873d1a930b8ea1f75c57"),
policyId: 1,
customerName: 'Michelle',
revision: 2,
itemsInsured: [ 'golf clubs', 'car', 'watch' ],
dateSet: ISODate("2024-04-16T14:12:24.476Z")
}Write the updated policy to the policyRevisions collection将更新的策略写入policyRevisions集合
db.currentPolicies.aggregate( [
{
$match: { policyId: 1 }
},
{
$set: { _id: new ObjectId() }
},
{
$merge: {
into: { db: "test", coll: "policyRevisions" },
on: "_id",
whenNotMatched: "insert"
}
}
] )
After you run the previous aggregation, the 运行之前的聚合后,policyRevisions collection contains both the original and updated policies: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
}
]Next Steps后续步骤
To view a customer's policy history, you can sort the 要查看客户的保单历史记录,您可以按修订对policyRevisions collection by revision. Consider if the customer Michelle makes another change to her policy and no longer wants to insure her golf clubs.policyRevisions集合进行排序。考虑一下客户Michelle是否再次更改了她的保单,不再想为她的高尔夫球杆投保。
Update the policy in the currentPolicies collection更新当前Policies集合中的策略
db.currentPolicies.updateOne(
{ policyId: 1 },
{
$pull: {
itemsInsured: "golf clubs"
},
$inc: {
revision: 1
},
$currentDate: {
dateSet: true
}
}
)
Updated document:更新文件:
{
_id: ObjectId("661e873d1a930b8ea1f75c57"),
policyId: 1,
customerName: 'Michelle',
revision: 3,
itemsInsured: [ 'car', 'watch' ],
dateSet: ISODate("2024-04-16T14:13:38.203Z")
}Write the updated policy to the policyRevisions collection将更新的策略写入policyRevisions集合
db.currentPolicies.aggregate( [
{
$match: { policyId: 1 }
},
{
$set: { _id: new ObjectId() }
},
{
$merge: {
into: { db: "test", coll: "policyRevisions" },
on: "_id",
whenNotMatched: "insert"
}
}
] )Return a history of the policy changes返回政策更改的历史记录
db.policyRevisions.find( { policyId: 1 } ).sort( { revision: 1 } )
Output:输出:
[
{
_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
}
]