{"id":1895,"date":"2013-07-14T10:32:29","date_gmt":"2013-07-14T15:32:29","guid":{"rendered":"http:\/\/www.wiredprairie.us\/blog\/?p=1895"},"modified":"2022-06-29T10:35:18","modified_gmt":"2022-06-29T15:35:18","slug":"using-inc-to-increment-a-field-in-a-sub-document-in-an-array-and-a-field-in-main-document","status":"publish","type":"post","link":"https:\/\/www.wiredprairie.us\/blog\/index.php\/archives\/1895","title":{"rendered":"Using $inc to increment a field in a sub-document in an array and a field in main document"},"content":{"rendered":"
(Blog post inspired by question I answered<\/a> on StackOverflow)<\/p>\n Lets say you have a schema in MongoDB that looks something like this:<\/p>\n Atomically, you\u2019d like to update two fields at one time, the total for a particular spelling which is in a sub document in an array, and the overall count field.<\/p>\n The way to handle this is to take advantage of the positional array operator<\/a> and the $inc<\/a><\/strong> operator.<\/p>\n Starting with just updating the count, that\u2019s easy:<\/p>\n The query matches on the document with the _id<\/strong> of star_wars<\/strong>, and increments the count <\/strong>by 1.<\/p>\n The positional operator is where the mongo-magic comes into play here. If you wanted to just update a single sub-document in the array, add it to the query. First, we\u2019ll try finding the right document:<\/p>\n That matches the right document, but also returns all of the elements of the array.<\/p>\n But, wait, there\u2019s more! When you match on an element\/document of an array, the position of the match is remembered and can be used in the update phase. You do that using the positional operator. Using the document above, you\u2019ll use this: spellings.$.total<\/strong>. If you knew the specific index into the array, the $<\/strong> could have been replaced with the zero-based index number (like a 1<\/strong> for example in this case: spellings.1.total<\/strong>).<\/p>\n Putting it all together then results in a slick and simple way of incrementing multiple fields in a document.<\/p>\n Results:<\/p>\n (Blog post inspired by question I answered on StackOverflow) Lets say you have a schema in MongoDB that looks something like this: { ‘_id’ : ‘star_wars’, ‘count’ : 1234, ‘spellings’ : [ { spelling: ‘Star wars’, total: 10}, { spelling: ‘Star Wars’, total : 15}, { spelling: ‘sTaR WaRs’, total : 5} ] } Atomically, […]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"spay_email":"","jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true},"categories":[4],"tags":[129],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/pd5QIe-uz","jetpack_likes_enabled":true,"jetpack-related-posts":[{"id":1857,"url":"https:\/\/www.wiredprairie.us\/blog\/index.php\/archives\/1857","url_meta":{"origin":1895,"position":0},"title":"Finding duplicates in MongoDB via the shell","date":"March 10, 2013","format":false,"excerpt":"I thought this was an interesting question to answer on StackOverflow (summarized here): I\u2019m trying to create an index, but an error is returned that duplicates exist for the field I want to index. What should I do? I answered with one possibility. The summary is that you can use\u2026","rel":"","context":"In "Coding"","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1835,"url":"https:\/\/www.wiredprairie.us\/blog\/index.php\/archives\/1835","url_meta":{"origin":1895,"position":1},"title":"How to rewrite a MongoDB C# LINQ with a Projection Requirement using a MongoCursor","date":"January 26, 2013","format":false,"excerpt":"The LINQ Provider for MongoDB does not currently take into account data projections efficiently when returning data. This could mean that you\u2019re unnecessarily returning more data from the database than is needed. So, I\u2019m going to show you the pattern I applied as a replacement for the LINQ queries when\u2026","rel":"","context":"In "Coding"","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1442,"url":"https:\/\/www.wiredprairie.us\/blog\/index.php\/archives\/1442","url_meta":{"origin":1895,"position":2},"title":"Nest Thermostat API\/Protocol","date":"January 8, 2012","format":false,"excerpt":"While Nest Labs hasn\u2019t released a formal (documented & supported) API, I thought I\u2019d do a bit of digging to see how they\u2019re using the network and what might be achievable. A few things are going on, the majority as you\u2019d probably expect. The web interface is using a long\u2026","rel":"","context":"In "Coding"","img":{"alt_text":"image","src":"https:\/\/i0.wp.com\/www.wiredprairie.us\/blog\/wp-content\/uploads\/2012\/01\/image_thumb7.png?resize=350%2C200","width":350,"height":200},"classes":[]},{"id":1833,"url":"https:\/\/www.wiredprairie.us\/blog\/index.php\/archives\/1833","url_meta":{"origin":1895,"position":3},"title":"How to view the MongoDB Query when using the C# LINQ Provider","date":"January 26, 2013","format":false,"excerpt":"If you\u2019re using the Official MongoDB C# Driver from 10gen, you may want to occasionally verify that the generated query matches your LINQ query (or at least that it\u2019s building something efficient). Take for example this query: var query = (from r in DataLayer.Database.GetCollection{\n '_id'<\/span> : 'star_wars'<\/span>,\n 'count'<\/span> : 1234,\n 'spellings'<\/span> : [ \n { spelling: 'Star wars'<\/span>, total: 10}, \n { spelling: 'Star Wars'<\/span>, total : 15}, \n { spelling: 'sTaR WaRs'<\/span>, total : 5} ]\n}<\/pre>\n
db.movies.update( \n {_id: \"star_wars\"<\/span>}, \n { $inc : { 'count'<\/span> : 1 }}\n)<\/pre>\n
db.movies.find( {\n _id: \"star_wars\"<\/span>, \n 'spellings.spelling'<\/span> : \"Star Wars\"<\/span> }\n)<\/pre>\n
db.movies.update( \n {_id: \"star_wars\"<\/span>,\n 'spellings.spelling'<\/span> : \"Star Wars\"<\/span> },\n { $inc : \n { 'spellings.$.total'<\/span> : 1, \n 'count'<\/span> : 1 }})<\/pre>\n
{\n '_id'<\/span> : 'star_wars'<\/span>,\n 'count'<\/span> : 1235,\n 'spellings'<\/span> : [ \n { spelling: 'Star wars'<\/span>, total: 10}, \n { spelling: 'Star Wars'<\/span>, total : 16}, \n { spelling: 'sTaR WaRs'<\/span>, total : 5} ]\n}<\/pre>\n","protected":false},"excerpt":{"rendered":"