{"id":661,"date":"2017-10-26T09:23:19","date_gmt":"2017-10-26T17:23:19","guid":{"rendered":"https:\/\/www.kenwalger.com\/blog\/?p=661"},"modified":"2018-01-16T11:05:03","modified_gmt":"2018-01-16T19:05:03","slug":"change-streams-coming-soon-mongodb-3-6","status":"publish","type":"post","link":"https:\/\/www.kenwalger.com\/blog\/nosql\/mongodb\/change-streams-coming-soon-mongodb-3-6\/","title":{"rendered":"Change Streams in MongoDB 3.6"},"content":{"rendered":"<p>Gone are the days when expectations of information were not instantaneous access to the data. In today&#8217;s world, people expect real-time results and information. What&#8217;s the moisture content of the soil around grapevine X right\u00a0<strong>now<\/strong>? Not yesterday, not five minutes ago, but now. Being notified about constantly changing data points is critical in many of today&#8217;s applications. In the latest 3.6 release of <a href=\"http:\/\/www.mongodb.com\">MongoDB<\/a> a new feature is being introduced to assist with these real-time expectations: Change Streams.<\/p>\n<h3>Change Streams Defined<\/h3>\n<p>Change streams are being implemented in the driver with a new <a href=\"https:\/\/docs.mongodb.com\/master\/aggregation\/\">aggregation<\/a> operator, <code>$changeStream<\/code> and <code>watch<\/code> method in the API. We can now specify a\u00a0<code>$changeStream<\/code> stage at the beginning of our pipeline and request that notifications are sent for specific changes to a particular collection.<\/p>\n<h3>Example Use Case<\/h3>\n<p>Let&#8217;s take the soil moisture example I stated earlier. Imagine that you have a farm with multiple\u00a0<a href=\"https:\/\/www.amazon.com\/gp\/product\/B06ZYVBRND\/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=9325&amp;creativeASIN=B06ZYVBRND&amp;linkCode=as2&amp;tag=kenwalgersite-20&amp;linkId=2e3515c3da625962cfafe8e820620418\" target=\"_blank\" rel=\"noopener\">moisture sensors<\/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=B06ZYVBRND\" alt=\"\" width=\"1\" height=\"1\" border=\"0\" \/>\u00a0or a\u00a0<a href=\"https:\/\/www.amazon.com\/gp\/product\/B011NEQ7J4\/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=9325&amp;creativeASIN=B011NEQ7J4&amp;linkCode=as2&amp;tag=kenwalgersite-20&amp;linkId=c8ee5dcc279985c2897c08b0ef5a504f\" target=\"_blank\" rel=\"noopener\">TMP36 Analog temperature<\/a>\u00a0sensor<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=B011NEQ7J4\" alt=\"\" width=\"1\" height=\"1\" border=\"0\" \/> connected to something like a <a href=\"https:\/\/www.amazon.com\/gp\/product\/B010O1G1ES\/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=9325&amp;creativeASIN=B010O1G1ES&amp;linkCode=as2&amp;tag=kenwalgersite-20&amp;linkId=85c3b431dbcb2773387af28ff09a6e4f\" target=\"_blank\" rel=\"noopener\">NodeMCU ESP8266<\/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=B010O1G1ES\" alt=\"\" width=\"1\" height=\"1\" border=\"0\" \/>\u00a0or <a href=\"https:\/\/www.amazon.com\/gp\/product\/B06W9GBL2W\/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=9325&amp;creativeASIN=B06W9GBL2W&amp;linkCode=as2&amp;tag=kenwalgersite-20&amp;linkId=11f52ad3f601e4e50c7a7799699da948\" target=\"_blank\" rel=\"noopener\">LoPy<\/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=B06W9GBL2W\" alt=\"\" width=\"1\" height=\"1\" border=\"0\" \/> device. Without going into detail about how to set the IoT network up, for the sake of our use case we can assume that they are sending readings back to a MongoDB server. Perhaps the data is being stored on <a href=\"https:\/\/www.kenwalger.com\/blog\/nosql\/mongodb\/mongodb-atlas\/\">MongoDB Atlas<\/a> even. I have, however, written about the <a href=\"https:\/\/www.kenwalger.com\/blog\/iot\/lopy\/\">LoPy microcontroller<\/a> and <a href=\"https:\/\/www.kenwalger.com\/blog\/iot\/micropython\/micropython-temperature-sensor\/\">ESP8266 with temperature<\/a> sensors in the past if you are interested in learning more.<\/p>\n<p>Anyway, for the sake of argument, let&#8217;s say that we need to know when the moisture content of the soil drops below a certain level. Moisture values on similar devices are measured as a raw number between 0-1024. The higher the number, the more moisture in the soil. For our use case, we need to know when the moisture level drops below 350 (too dry).<\/p>\n<h6>Change Stream in action<\/h6>\n<p>Since these recordings are frequently changing, we can set up a change stream to get notified. It&#8217;s fairly straightforward to establish a notification with the <code>watch<\/code> method. We could set something like this up:<\/p>\n<pre>change_stream = client.winery.collection.watch([\n  {'$match': {\n       'operationType': {'$in': ['insert']}\n    }},\n    {'$match': {\n        'moisture_level': {'$lt': 350}\n    }}\n]);\nfor change in change_stream:\n    turn_on_water();\n    # Something else magical<\/pre>\n<p>Now when we have an insert into the database where the <code>moisture_level<\/code> is below 350, we&#8217;ll turn our watering system on along with whatever else needs to be done. We could set up a similar change stream for when the moisture level gets high enough to warrant\u00a0shutting the system off at 450.<\/p>\n<p>This is but one example of where change streams would be a useful tool. Updating reports dynamically on data changes, publish\/subscribe types of functionality, brokers, and many other use cases are now open to native MongoDB actions.<\/p>\n<h3>Change Steam Details<\/h3>\n<p>You&#8217;ll notice that there is an <code>operationType<\/code> being looked at there. Change streams look at five different events, or Operation Types<\/p>\n<ul>\n<li>Insert<\/li>\n<li>Delete<\/li>\n<li>Replace (everything but the unique id)<\/li>\n<li>Update<\/li>\n<li>Invalidate (in cases of an invalid cursor being returned)<\/li>\n<\/ul>\n<p>Change streams also utilize access controls and can be set up based on <a href=\"https:\/\/docs.mongodb.com\/manual\/reference\/built-in-roles\/\">user roles<\/a>. They present a defined API and enable scaling across primaries and secondaries. MongoDB is supporting up to 1,000 concurrent change streams per data bearing node in 3.6.<\/p>\n<p>They are durable, meaning they rely on the data being majority committed in a <a href=\"https:\/\/docs.mongodb.com\/manual\/replication\/index.html\">replica set<\/a>. The order of the changes in data is important too, right? 3.6 also introduces a global logical clock which, among other uses, will ensure that clients always will get changes in the order they occurred on the server. This is very important for <code>replace<\/code> and <code>update<\/code> operations.<\/p>\n<h3>Wrap Up<\/h3>\n<p>There are a lot more technical details about change streams forthcoming as 3.6 moves closer to production and documentation is further flushed out. Change streams are inherent in the 3.6 Server and are available in both the community and enterprise versions of the product. MongoDB Version 3.6 is available to <a href=\"https:\/\/www.mongodb.com\/download-center\">download<\/a> today as a release candidate. Which means that while the high-level concepts of change streams discussed here likely will remain in tack in the final release, there may be some subtle changes. That being said, change streams are a great feature being implemented in the new release. If your applications require\u00a0or could use real-time information, I would encourage you to have a look.<\/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.<\/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.<\/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%2F661&#038;t=Change%20Streams%20in%20MongoDB%203.6&#038;s=100&#038;p&#091;url&#093;=https%3A%2F%2Fwww.kenwalger.com%2Fblog%2Fwp-json%2Fwp%2Fv2%2Fposts%2F661&#038;p&#091;images&#093;&#091;0&#093;=https%3A%2F%2Fi0.wp.com%2Fwww.kenwalger.com%2Fblog%2Fwp-content%2Fuploads%2F2017%2F10%2Fchange_streams_feature.png%3Ffit%3D125%252C125%26ssl%3D1&#038;p&#091;title&#093;=Change%20Streams%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%2F661&#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%2F661&#038;title=Change%20Streams%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%2F661&#038;title=Change%20Streams%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=Change%20Streams%20in%20MongoDB%203.6&#038;body=Hey%20check%20this%20out:%20https%3A%2F%2Fwww.kenwalger.com%2Fblog%2Fwp-json%2Fwp%2Fv2%2Fposts%2F661\" 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>Gone are the days when expectations of information were not instantaneous access to the data. In today&#8217;s world, people expect real-time results and information. What&#8217;s the moisture content of the soil around grapevine X right\u00a0now? Not yesterday, not five minutes ago, but now. Being notified about constantly changing data points is critical in many of &hellip; <a href=\"https:\/\/www.kenwalger.com\/blog\/nosql\/mongodb\/change-streams-coming-soon-mongodb-3-6\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Change Streams in MongoDB 3.6&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":662,"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":[27,4],"tags":[1083,36],"yst_prominent_words":[1056,1062,1059,1081,1058,1065,1075,99,389,813,1066,1072,1074,1082,87,1057,805,951,1084,1060],"class_list":["post-661","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-iot","category-mongodb","tag-change-streams","tag-esp8266","pmpro-has-access"],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/www.kenwalger.com\/blog\/wp-content\/uploads\/2017\/10\/change_streams_feature.png?fit=125%2C125&ssl=1","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p8lx70-aF","jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/www.kenwalger.com\/blog\/wp-json\/wp\/v2\/posts\/661","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=661"}],"version-history":[{"count":6,"href":"https:\/\/www.kenwalger.com\/blog\/wp-json\/wp\/v2\/posts\/661\/revisions"}],"predecessor-version":[{"id":775,"href":"https:\/\/www.kenwalger.com\/blog\/wp-json\/wp\/v2\/posts\/661\/revisions\/775"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.kenwalger.com\/blog\/wp-json\/wp\/v2\/media\/662"}],"wp:attachment":[{"href":"https:\/\/www.kenwalger.com\/blog\/wp-json\/wp\/v2\/media?parent=661"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.kenwalger.com\/blog\/wp-json\/wp\/v2\/categories?post=661"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.kenwalger.com\/blog\/wp-json\/wp\/v2\/tags?post=661"},{"taxonomy":"yst_prominent_words","embeddable":true,"href":"https:\/\/www.kenwalger.com\/blog\/wp-json\/wp\/v2\/yst_prominent_words?post=661"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}