{"id":704,"date":"2017-11-28T12:58:30","date_gmt":"2017-11-28T20:58:30","guid":{"rendered":"https:\/\/www.kenwalger.com\/blog\/?p=704"},"modified":"2017-11-28T12:58:30","modified_gmt":"2017-11-28T20:58:30","slug":"schema-validation-mongodb-3-6","status":"publish","type":"post","link":"https:\/\/www.kenwalger.com\/blog\/nosql\/mongodb\/schema-validation-mongodb-3-6\/","title":{"rendered":"Schema Validation in MongoDB 3.6"},"content":{"rendered":"<p>MongoDB 3.6 brings lots of great new features with the new release. I&#8217;ve already covered <a href=\"https:\/\/www.kenwalger.com\/blog\/nosql\/mongodb\/change-streams-coming-soon-mongodb-3-6\/\">Change Streams<\/a> and <a href=\"https:\/\/www.kenwalger.com\/blog\/nosql\/mongodb\/retryable-writes\/\">Retryable Writes<\/a> in previous posts. This post will cover a feature which expands upon the <a href=\"https:\/\/docs.mongodb.com\/manual\/core\/document-validation\/\">document validation<\/a> feature from MongoDB 3.2, schema validation. Schema validation allows for teams to define a prescribed document structure for each collection.<\/p>\n<p>There are times when enforcing strict data structures and content are required, even with the flexible schema and <a href=\"https:\/\/www.kenwalger.com\/blog\/nosql\/document-model\/\">document data model<\/a> that <a href=\"https:\/\/www.mongodb.com\">MongoDB<\/a> provides. Schema validation allows for the ability to define a prescribed document structure for each collection. If one tries to insert or update a document which does\u00a0<em>not<\/em> conform to the applied structure the operation can be rejected. The rules for document structure are based on the <a href=\"http:\/\/json-schema.org\/\">J<\/a><a href=\"http:\/\/json-schema.org\/\">SON schema draft specification<\/a>.<\/p>\n<h3>Schema Validation<\/h3>\n<p>Let&#8217;s take a quick look at how this works in action before diving into a discussion of feature benefits.<\/p>\n<p>Imagine a collection of food recipes. Each recipe will have a recipe name, number of servings, cooking method, ingredients, and list of instructions. For the\u00a0ingredients, we\u00a0want to enforce that there is a numerical quantity, a measure of quantity, the ingredient name, and an optional value for any prep work on the ingredient, such as &#8220;peeled&#8221; or &#8220;<a href=\"https:\/\/www.amazon.com\/gp\/product\/0470421355\/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=9325&amp;creativeASIN=0470421355&amp;linkCode=as2&amp;tag=kenwalgersite-20&amp;linkId=d679d531adba3349c14bcf9f8a731651\" target=\"_blank\" rel=\"noopener\">brunoise<\/a><img loading=\"lazy\" decoding=\"async\" style=\"border: none !important; margin: 0px !important;\" src=\"\/\/ir-na.amazon-adsystem.com\/e\/ir?t=kenwalgersite-20&amp;l=am2&amp;o=1&amp;a=0470421355\" alt=\"\" width=\"1\" height=\"1\" border=\"0\" \/>&#8220;.\u00a0 For our example here my options are not all-inclusive for options but simply serve as examples. I hope my former culinary colleagues forgive me.<\/p>\n<p>We&#8217;ll begin with creating a <code>recipes<\/code> collection and assigning the schema validation rules with the <code>validator<\/code> option and the new <a href=\"https:\/\/docs.mongodb.com\/master\/reference\/operator\/query\/jsonSchema\/#op._S_jsonSchema\">$jsonSchema<\/a> operator.<\/p>\n<pre>db.createCollection( \"recipes\",\n{\n  validator: \n    {\n      $jsonSchema:\n        {\n          bsonType: \"object\",\n          required: [\"name\", \"servings\", \"ingredients\"],\n          additionalProperties: false,\n          properties:\n            {\n              _id: {},\n              name: {\n                bsonType: \"string\",\n                description: \"'name' is required and is a string\"\n                    },\n              servings: {\n                bsonType: [\"int\", \"double\"],\n                minimum: 0,\n                description: \"'servings' is required and must be an integer greater than zero.\"\n                    },\n              cooking_method: {\n                 enum: [\"broil\", \"grill\", \"roast\", \"bake\", \"saute\", \"pan-fry\", \"deep-fry\", \"poach\", \"simmer\", \"boil\", \"steam\", \"braise\", \"stew\"],\n              description: \"'cooking_method' is optional but, if used, must be one of the listed options.\"\n                    },\n              ingredients: \n              {\n                bsonType: [\"array\"],\n                minItems: 1,\n                maxItems: 50,\n                items: {\n                  bsonType: [\"object\"],     \n                  required: [\"quantity\", \"measure\", \"ingredient\"],\n                  additionalProperties: false,\n                  description: \"'ingredients' must contain the stated fields.\",\n                  properties: \n                  {\n                    quantity: {\n                      bsonType: [\"double\", \"decimal\"],\n                      description: \"'quantity' is required and is of double or decimal type\"\n                            },\n                    measure: {\n                      enum: [\"tsp\", \"Tbsp\", \"cup\", \"ounce\", \"pound\",  \"each\"],\n                      description: \"'measure' is required and can only be one of the given enum values\"\n                            },\n                    ingredient: {\n                      bsonType: \"string\",\n                      description: \"'ingredient' is required and is a string\"\n                            },\n                    format: {\n                      bsonType: \"string\",\n                      description: \"'format' is an optional field of type string\"\n                            }\n                  }\n              }\n           }\n        }\n     }\n   }\n})<\/pre>\n<p>Our <code>validator<\/code> can include many <a href=\"https:\/\/docs.mongodb.com\/master\/reference\/operator\/query\/jsonSchema\/#doc-insert-schema-validation\">more rules<\/a> that are beyond the scope of this introduction to schema validation. However, we can see how powerful this feature is in this small example. Let&#8217;s look at some example documents to insert as well to see what would happen if we try to <a href=\"https:\/\/docs.mongodb.com\/manual\/reference\/method\/db.collection.insert\/\">insert<\/a> a <a href=\"https:\/\/docs.mongodb.com\/manual\/core\/document\/index.html\">document<\/a> into the <a href=\"https:\/\/docs.mongodb.com\/manual\/core\/databases-and-collections\/index.html\">collection<\/a>.<\/p>\n<h6>Sample Inserts<\/h6>\n<pre>db.recipes.insertOne({name: \"Chocolate Sponge Cake Filling\", \nservings: 4, \ningredients: [{quantity: 7, measure: \"ounce\", ingredient: \"bittersweet chocolate\", format: \"chopped\"}, \n{quantity: 2, measure: \"cup\", ingredient: \"heavy cream\"}\n]})<\/pre>\n<p>This insert works since it covers all of the required fields in their proper format. It also doesn&#8217;t include any invalid extra fields which would be prohibited since we have\u00a0<code>additionalProperties: false<\/code> set. If we were to try to insert the following document, however, we would get an error.<\/p>\n<pre>db.recipes.insertOne({name: \"Chocolate Sponge Cake Filling\", \nservings: 4, \ningredients: [{quantity: 7, measure: \"ounce\", ingredient: \"bittersweet chocolate\", format: \"chopped\"}, \n{quantity: 2, measure: \"cup\", ingredient: \"heavy cream\"}],\ndirections: \"Boil cream and pour over chocolate. Stir until chocolate is melted.\"\n})<\/pre>\n<p>Since we added in a <code>directions<\/code> field into our recipe document, the insert will fail with\u00a0<code>additionalProperties: false<\/code>\u00a0set. I should add in an optional <code>directions<\/code> field into the schema validation to allow for that as directions are indeed important.<\/p>\n<h3>Schema Validation Benefits<\/h3>\n<p>Even with these basic examples, I think it is clear that schema validation is a great new enhancement. The flexibility of a dynamic schema in MongoDB can now easily be paired with data governance controls over an entire collection. While there are lots of practical benefits from this, here are some specific benefits.<\/p>\n<ol>\n<li>Application logic simplification. With a strictly defined definition of what a collection looks like, there isn&#8217;t a need for the application to handle the guarantees and associated errors.<\/li>\n<li>Control of data. Client applications must adhere to the rules set forth by the collection. No need to worry about data being updated or inserted that has incorrect field names or data types.<\/li>\n<li>Governmental compliance. There are applications and data models in a variety of industries and locales that require data to be stored in specific formats. For example, the <a href=\"https:\/\/www.amazon.com\/gp\/product\/184928945X\/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=9325&amp;creativeASIN=184928945X&amp;linkCode=as2&amp;tag=kenwalgersite-20&amp;linkId=da741c9e3ba84c6d499cac9f9a96a5bd\" target=\"_blank\" rel=\"noopener\">EU General Data Protection Regulation<\/a><img loading=\"lazy\" decoding=\"async\" style=\"border: none !important; margin: 0px !important;\" src=\"\/\/ir-na.amazon-adsystem.com\/e\/ir?t=kenwalgersite-20&amp;l=am2&amp;o=1&amp;a=184928945X\" alt=\"\" width=\"1\" height=\"1\" border=\"0\" \/> in the European Union.<\/li>\n<\/ol>\n<h3>Wrap Up<\/h3>\n<p>With MongoDB 3.6 schema validation, administrators have tunable controls over the database. Documents that don&#8217;t conform to a prescribed set of conditions can be rejected or still written and a message logged about the action. It also brings with it the ability to query based on the schema definition to allow,\u00a0for example, a search on all documents that\u00a0<em>don&#8217;t<\/em> conform to the schema.<\/p>\n<p>Schema validation is another exciting feature in the 3.6 release of MongoDB. I would urge you to <a href=\"https:\/\/www.monogdb.com\/download-center\">download<\/a> it and try it out. I&#8217;d bet you&#8217;ll be as excited about it as I am.<\/p>\n<hr \/>\n<p>Follow me on Twitter <a href=\"https:\/\/www.twitter.com\/kenwalger\">@kenwalger<\/a> to get the latest updates on my postings. Or better yet, sign up for the email list to get updates in your mailbox!<\/p>\n<p>There are a few MongoDB specific terms in this post. I created a <a href=\"https:\/\/www.echoskillstore.com\/MongoDB-Dictionary\/45103\">MongoDB Dictionary<\/a> skill for the <a href=\"https:\/\/www.amazon.com\/gp\/product\/B01DFKC2SO\/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=9325&amp;creativeASIN=B01DFKC2SO&amp;linkCode=as2&amp;tag=kenwalgersite-20&amp;linkId=f9e513223de2525a72b95cf9561db55b\" rel=\"noopener noreferrer\">Amazon Echo<\/a>\u00a0line of products. Check it out and you can say &#8220;Alexa, ask MongoDB for the definition of a\u00a0document?&#8221; and get a helpful response.\u00a0I also created a <a href=\"https:\/\/www.echoskillstore.com\/Kens-Culinary-Glossary\/B072JXS3L5\">culinary skill<\/a> for the Echo if you&#8217;d like to update your culinary knowledge as well.<\/p>\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%2F704&#038;t=Schema%20Validation%20in%20MongoDB%203.6&#038;s=100&#038;p&#091;url&#093;=https%3A%2F%2Fwww.kenwalger.com%2Fblog%2Fwp-json%2Fwp%2Fv2%2Fposts%2F704&#038;p&#091;images&#093;&#091;0&#093;=https%3A%2F%2Fi0.wp.com%2Fwww.kenwalger.com%2Fblog%2Fwp-content%2Fuploads%2F2017%2F11%2Fdocument_validation_feature-e1511822206981.png%3Ffit%3D125%252C125%26ssl%3D1&#038;p&#091;title&#093;=Schema%20Validation%20in%20MongoDB%203.6\" 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%2F704&#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%2F704&#038;title=Schema%20Validation%20in%20MongoDB%203.6\" 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%2F704&#038;title=Schema%20Validation%20in%20MongoDB%203.6\" 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=Schema%20Validation%20in%20MongoDB%203.6&#038;body=Hey%20check%20this%20out:%20https%3A%2F%2Fwww.kenwalger.com%2Fblog%2Fwp-json%2Fwp%2Fv2%2Fposts%2F704\" 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>MongoDB 3.6 brings lots of great new features with the new release. I&#8217;ve already covered Change Streams and Retryable Writes in previous posts. This post will cover a feature which expands upon the document validation feature from MongoDB 3.2, schema validation. Schema validation allows for teams to define a prescribed document structure for each collection. &hellip; <a href=\"https:\/\/www.kenwalger.com\/blog\/nosql\/mongodb\/schema-validation-mongodb-3-6\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Schema Validation in MongoDB 3.6&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":709,"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":[1102,1142],"yst_prominent_words":[117,99,1147,1150,1149,298,1152,360,1061,1163,87,1099,1153,1151,782,1143,1144,1154,1141,1145],"class_list":["post-704","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-mongodb","tag-3-6","tag-schema-validation","pmpro-has-access"],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/www.kenwalger.com\/blog\/wp-content\/uploads\/2017\/11\/document_validation_feature-e1511822206981.png?fit=125%2C125&ssl=1","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p8lx70-bm","jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/www.kenwalger.com\/blog\/wp-json\/wp\/v2\/posts\/704","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=704"}],"version-history":[{"count":5,"href":"https:\/\/www.kenwalger.com\/blog\/wp-json\/wp\/v2\/posts\/704\/revisions"}],"predecessor-version":[{"id":715,"href":"https:\/\/www.kenwalger.com\/blog\/wp-json\/wp\/v2\/posts\/704\/revisions\/715"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.kenwalger.com\/blog\/wp-json\/wp\/v2\/media\/709"}],"wp:attachment":[{"href":"https:\/\/www.kenwalger.com\/blog\/wp-json\/wp\/v2\/media?parent=704"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.kenwalger.com\/blog\/wp-json\/wp\/v2\/categories?post=704"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.kenwalger.com\/blog\/wp-json\/wp\/v2\/tags?post=704"},{"taxonomy":"yst_prominent_words","embeddable":true,"href":"https:\/\/www.kenwalger.com\/blog\/wp-json\/wp\/v2\/yst_prominent_words?post=704"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}