{"id":1074,"date":"2019-04-18T07:07:33","date_gmt":"2019-04-18T14:07:33","guid":{"rendered":"https:\/\/www.kenwalger.com\/blog\/?p=1074"},"modified":"2019-04-12T13:13:17","modified_gmt":"2019-04-12T20:13:17","slug":"building-with-patterns-the-document-versioning-pattern","status":"publish","type":"post","link":"https:\/\/www.kenwalger.com\/blog\/nosql\/mongodb\/building-with-patterns-the-document-versioning-pattern\/","title":{"rendered":"Building with Patterns: The Document Versioning Pattern"},"content":{"rendered":"\n<p>Databases, such as MongoDB, are very good at querying lots of data and updating that data frequently. In most cases, however, we are only performing queries on the latest state of the data. What about situations in which we need to query <em>previous<\/em> states of the data? What if we need to have some functionality of version control of our documents? This is where we can use the Document Versioning Pattern.<\/p>\n\n\n\n<p>This pattern is all about keeping the version history of documents available and usable. We could construct a system that uses a dedicated version control system in conjunction with MongoDB. One system for the few documents that change and MongoDB for the others. This would be potentially cumbersome. By using the Document Versioning Pattern, however, we are able to avoid having to use multiple systems for managing the current documents and their history by keeping them in one database. <\/p>\n\n\n\n<h4 class=\"wp-block-heading\">The Document Versioning Pattern<\/h4>\n\n\n\n<p>This pattern addresses the problem of wanting to keep around older revisions of some documents in MongoDB instead of bringing in a second management system. To accomplish this, we add a field to each document allowing us to keep track of the document version. The database will then have two collections: one that has the latest (and most queried data) and another that has all of the revisions of the data.<\/p>\n\n\n\n<p>The Document Versioning Pattern makes a few assumptions about the data in the database and the data access patterns that the application makes.<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Each document doesn\u2019t have too many revisions.<\/li><li>There aren\u2019t too many documents to version.<\/li><li>Most of the queries performed are done on the most current version of the document.<\/li><\/ol>\n\n\n\n<p>If you find that these assumptions don\u2019t fit your use case, this pattern may not be a great fit. You may have to alter how you implement your version of the Document Versioning Pattern or your use case may simply require a different solution.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Sample Use Case<\/h4>\n\n\n\n<p>The Document Versioning Pattern is very useful in highly regulated industries that require a specific point in time version of a set of data. Financial and healthcare industries are good examples. Insurance and legal industries are some others. There are many use cases that track histories of some portion of the data.<\/p>\n\n\n\n<p>Think of how an insurance company might make use of this pattern. Each customer has a \u201cstandard\u201d policy and a second portion that is specific to that customer, a policy rider if you will. This second portion would contain a list of policy add-ons and a list of specific items that are being insured. As the customer changes what specific items are insured, this information needs to be updated while the historical information needs to be available as well. This is fairly common in homeowner or renters insurance policies. For example, if someone has specific items they want to be insured beyond the typical coverage provided, they are listed separately, as a rider. Another use case for the insurance company may be to keep all the versions of the &#8220;standard policy&#8221; they have mailed to their customers over time.<\/p>\n\n\n\n<p>If we take a look at the requirements for the Document Versioning Pattern, this seems like a great use case. The insurance company likely has a few million customers, the revisions to the \u201cadd-on\u201d list likely don\u2019t occur too frequently, and the majority of searches on a policy will be about the most current version.<\/p>\n\n\n\n<p>Inside our database, each customer might have a <code>current_policy<\/code> document \u2014 containing customer specific information \u2014 in a <code>current_policies<\/code> collection and <code>policy_revision<\/code> documents in a <code>policy_revisions<\/code> collection. Additionally, there would be a <code>standard_policy<\/code> collection that would be the same for most customers. When a customer purchases a new item and wants it added to their policy, a new <code>policy_revision<\/code> document is created using the <code>current_policy<\/code> document. A version field in the document is then incremented to identify it as the latest revision and the customer&#8217;s changes added.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/webassets.mongodb.com\/_com_assets\/cms\/documentversioning0-qex0ek1957.png?w=840&#038;ssl=1\" alt=\"\"\/><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/webassets.mongodb.com\/_com_assets\/cms\/document_ver_2a-mw8mlpazzy.png?w=840&#038;ssl=1\" alt=\"Policy Revisions and Current Policy\"\/><\/figure>\n\n\n\n<p>The newest revision will be stored in the <code>current_policies<\/code> collection and the old version will be written to the <code>policy_revisions<\/code> collection. By keeping the latest versions in the <code>current_policy<\/code> collection queries can remain simple. The <code>policy_revisions<\/code> collection might only keep a few versions back as well, depending on data needs and requirements.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/webassets.mongodb.com\/_com_assets\/cms\/document_ver_3a-nqhnglt0yj.png?w=840&#038;ssl=1\" alt=\"Policy Revisions and Current Policy Collections\"\/><\/figure>\n\n\n\n<p>In this example then,  <em>Middle-earth Insurance<\/em> would have a <code>standard_policy<\/code> for its customers. All residents of <em>The Shire<\/em> would share this particular policy document. Bilbo has specific things he wants insuring on top of his normal coverage. His <em>Elven Sword<\/em> and, eventually, the <em>One Ring<\/em> are added to his policy. These would reside in the <code>current_policies<\/code> collection and as changes are made the <code>policy_revisions<\/code> collection would keep a historical record of changes.<\/p>\n\n\n\n<p>The Document Versioning Pattern is relatively easy to accomplish. It can be implemented on existing systems without too many changes to the application or to existing documents. Further, queries accessing the latest version of the document remain performant. <\/p>\n\n\n\n<p>One drawback to this pattern is the need to access a different collection for historical information. Another is the fact that writes will be higher overall to the database. This is why one of the requirements to use this pattern is that it occurs on data that isn\u2019t changed too frequently.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p>When you need to keep track of changes to documents, the Document Versioning Pattern is a great option. It is relatively easy to implement and can be applied to an existing set of documents. Another benefit is that queries to the latest version of data still perform well. It does not, however, replace a dedicated version control system. <\/p>\n\n\n\n<p>The next post in this series will look at the final design pattern, <em>Schema Versioning<\/em>.<\/p>\n\n\n\n<p>If you have questions, please leave comments below. <\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Previous Parts of Building with Patterns:<\/h4>\n\n\n\n<ul class=\"wp-block-list\"><li>The <a href=\"https:\/\/www.mongodb.com\/blog\/post\/building-with-patterns-the-polymorphic-pattern\">Polymorphic<\/a> pattern<\/li><li>The <a href=\"https:\/\/www.mongodb.com\/blog\/post\/building-with-patterns-the-attribute-pattern\">Attribute<\/a> pattern<\/li><li>The <a href=\"https:\/\/www.mongodb.com\/blog\/post\/building-with-patterns-the-bucket-pattern\">Bucket<\/a> pattern<\/li><li>The <a href=\"https:\/\/www.mongodb.com\/blog\/post\/building-with-patterns-the-outlier-pattern\">Outlier<\/a> pattern<\/li><li>The <a href=\"https:\/\/www.mongodb.com\/blog\/post\/building-with-patterns-the-computed-pattern\">Computed<\/a> pattern<\/li><li>The <a href=\"https:\/\/www.mongodb.com\/blog\/post\/building-with-patterns-the-subset-pattern\">Subset<\/a> pattern<\/li><li>The <a href=\"https:\/\/www.mongodb.com\/blog\/post\/building-with-patterns-the-extended-reference-pattern\">Extended Reference<\/a> pattern<\/li><li>The <a href=\"https:\/\/www.mongodb.com\/blog\/post\/building-with-patterns-the-approximation-reference-pattern\">Approximation<\/a> pattern<\/li><li>The <a href=\"https:\/\/www.mongodb.com\/blog\/post\/building-with-patterns-the-tree-pattern\">Tree<\/a> pattern<\/li><li>The <a href=\"https:\/\/www.mongodb.com\/blog\/post\/building-with-patterns-the-preallocation-pattern\">Pre-allocation<\/a> pattern<\/li><\/ul>\n<a class=\"synved-social-button synved-social-button-share synved-social-size-48 synved-social-resolution-single synved-social-provider-facebook nolightbox\" data-provider=\"facebook\" target=\"_blank\" rel=\"nofollow\" title=\"Share on Facebook\" href=\"https:\/\/www.facebook.com\/sharer.php?u=https%3A%2F%2Fwww.kenwalger.com%2Fblog%2Fwp-json%2Fwp%2Fv2%2Fposts%2F1074&#038;t=Building%20with%20Patterns%3A%20The%20Document%20Versioning%20Pattern&#038;s=100&#038;p&#091;url&#093;=https%3A%2F%2Fwww.kenwalger.com%2Fblog%2Fwp-json%2Fwp%2Fv2%2Fposts%2F1074&#038;p&#091;images&#093;&#091;0&#093;=https%3A%2F%2Fwebassets.mongodb.com%2F_com_assets%2Fcms%2Fdocumentversioning0-qex0ek1957.png&#038;p&#091;title&#093;=Building%20with%20Patterns%3A%20The%20Document%20Versioning%20Pattern\" style=\"font-size: 0px;width:48px;height:48px;margin:0;margin-bottom:5px;margin-right:5px\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" alt=\"Facebook\" title=\"Share on Facebook\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"48\" height=\"48\" style=\"display: inline;width:48px;height:48px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/i0.wp.com\/www.kenwalger.com\/blog\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/96x96\/facebook.png?resize=48%2C48&#038;ssl=1\" \/><\/a><a class=\"synved-social-button synved-social-button-share synved-social-size-48 synved-social-resolution-single synved-social-provider-twitter nolightbox\" data-provider=\"twitter\" target=\"_blank\" rel=\"nofollow\" title=\"Share on Twitter\" href=\"https:\/\/twitter.com\/intent\/tweet?url=https%3A%2F%2Fwww.kenwalger.com%2Fblog%2Fwp-json%2Fwp%2Fv2%2Fposts%2F1074&#038;text=Hey%20check%20this%20out\" style=\"font-size: 0px;width:48px;height:48px;margin:0;margin-bottom:5px;margin-right:5px\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" alt=\"twitter\" title=\"Share on Twitter\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"48\" height=\"48\" style=\"display: inline;width:48px;height:48px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/i0.wp.com\/www.kenwalger.com\/blog\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/96x96\/twitter.png?resize=48%2C48&#038;ssl=1\" \/><\/a><a class=\"synved-social-button synved-social-button-share synved-social-size-48 synved-social-resolution-single synved-social-provider-reddit nolightbox\" data-provider=\"reddit\" target=\"_blank\" rel=\"nofollow\" title=\"Share on Reddit\" href=\"https:\/\/www.reddit.com\/submit?url=https%3A%2F%2Fwww.kenwalger.com%2Fblog%2Fwp-json%2Fwp%2Fv2%2Fposts%2F1074&#038;title=Building%20with%20Patterns%3A%20The%20Document%20Versioning%20Pattern\" style=\"font-size: 0px;width:48px;height:48px;margin:0;margin-bottom:5px;margin-right:5px\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" alt=\"reddit\" title=\"Share on Reddit\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"48\" height=\"48\" style=\"display: inline;width:48px;height:48px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/i0.wp.com\/www.kenwalger.com\/blog\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/96x96\/reddit.png?resize=48%2C48&#038;ssl=1\" \/><\/a><a class=\"synved-social-button synved-social-button-share synved-social-size-48 synved-social-resolution-single synved-social-provider-linkedin nolightbox\" data-provider=\"linkedin\" target=\"_blank\" rel=\"nofollow\" title=\"Share on Linkedin\" href=\"https:\/\/www.linkedin.com\/shareArticle?mini=true&#038;url=https%3A%2F%2Fwww.kenwalger.com%2Fblog%2Fwp-json%2Fwp%2Fv2%2Fposts%2F1074&#038;title=Building%20with%20Patterns%3A%20The%20Document%20Versioning%20Pattern\" style=\"font-size: 0px;width:48px;height:48px;margin:0;margin-bottom:5px;margin-right:5px\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" alt=\"linkedin\" title=\"Share on Linkedin\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"48\" height=\"48\" style=\"display: inline;width:48px;height:48px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/i0.wp.com\/www.kenwalger.com\/blog\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/96x96\/linkedin.png?resize=48%2C48&#038;ssl=1\" \/><\/a><a class=\"synved-social-button synved-social-button-share synved-social-size-48 synved-social-resolution-single synved-social-provider-mail nolightbox\" data-provider=\"mail\" rel=\"nofollow\" title=\"Share by email\" href=\"mailto:?subject=Building%20with%20Patterns%3A%20The%20Document%20Versioning%20Pattern&#038;body=Hey%20check%20this%20out:%20https%3A%2F%2Fwww.kenwalger.com%2Fblog%2Fwp-json%2Fwp%2Fv2%2Fposts%2F1074\" style=\"font-size: 0px;width:48px;height:48px;margin:0;margin-bottom:5px\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" alt=\"mail\" title=\"Share by email\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"48\" height=\"48\" style=\"display: inline;width:48px;height:48px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/i0.wp.com\/www.kenwalger.com\/blog\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/96x96\/mail.png?resize=48%2C48&#038;ssl=1\" \/><\/a>","protected":false},"excerpt":{"rendered":"<p>Databases, such as MongoDB, are very good at querying lots of data and updating that data frequently. In most cases, however, we are only performing queries on the latest state of the data. What about situations in which we need to query previous states of the data? What if we need to have some functionality &hellip; <a href=\"https:\/\/www.kenwalger.com\/blog\/nosql\/mongodb\/building-with-patterns-the-document-versioning-pattern\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Building with Patterns: The Document Versioning Pattern&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"pmpro_default_level":"","_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[4],"tags":[1612,785],"yst_prominent_words":[117,1609,99,1608,1603,1601,298,1599,1598,538,1611,1606,507,1610,339,1605,1604,1602,1607,1600],"class_list":["post-1074","post","type-post","status-publish","format-standard","hentry","category-mongodb","tag-document-versioning-pattern","tag-schema-design","pmpro-has-access"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p8lx70-hk","jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/www.kenwalger.com\/blog\/wp-json\/wp\/v2\/posts\/1074","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.kenwalger.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.kenwalger.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.kenwalger.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.kenwalger.com\/blog\/wp-json\/wp\/v2\/comments?post=1074"}],"version-history":[{"count":1,"href":"https:\/\/www.kenwalger.com\/blog\/wp-json\/wp\/v2\/posts\/1074\/revisions"}],"predecessor-version":[{"id":1075,"href":"https:\/\/www.kenwalger.com\/blog\/wp-json\/wp\/v2\/posts\/1074\/revisions\/1075"}],"wp:attachment":[{"href":"https:\/\/www.kenwalger.com\/blog\/wp-json\/wp\/v2\/media?parent=1074"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.kenwalger.com\/blog\/wp-json\/wp\/v2\/categories?post=1074"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.kenwalger.com\/blog\/wp-json\/wp\/v2\/tags?post=1074"},{"taxonomy":"yst_prominent_words","embeddable":true,"href":"https:\/\/www.kenwalger.com\/blog\/wp-json\/wp\/v2\/yst_prominent_words?post=1074"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}