ドキュメントのバージョンの履歴を保持する
データが変更された場合、一部のアプリケーションは古いバージョンのデータを利用可能にする必要があります。 ドキュメント バージョン管理パターンでは、古いデータバージョンは現在のデータとは別のコレクションに保持されます。
ドキュメント バージョン管理パターンを使用すると、現在のドキュメントとその履歴を同じデータベースに保存し、データ履歴を管理するために複数のシステムを使用する必要がないようにできます。
このタスクについて
データが次の条件を満たす場合、 ドキュメント バージョン管理パターン は最適に機能します。
ドキュメントはほとんど更新されません。
バージョン追跡が必要なドキュメントは少ないです。
現在のデータと履歴データは通常、個別にクエリされます。 ドキュメント バージョン管理パターンでは、履歴データは現在のデータとは別のコレクションに保存されるため、同じ操作で両方を返すとコストが高くなる可能性があります。
上記の基準がユースケースに適合しない場合は、別のソリューションを検討するか、ドキュメント バージョン管理パターンの実装方法を変更してください。
始める前に
次の例では、保証会社は ドキュメント バージョン管理パターン を使用してカスタマー ポリシーの変更を追跡しています。 サンプル ドキュメントを 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 がポリシーに監視を追加したい場合、アプリケーションは次の操作を実行します。
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") }
更新されたポリシーを policiesReplications コレクションに書込み (write)
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 がポリシーを別の変更を行い、追加のルールでルールを説明しなくなりました。
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") }
ポリシーの変更の履歴を返す
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 } ]