Query and Update documents nested multiple levels in an array

The $ positional operator is used to project elements in an array based on a condition. The $ operator can be used to project fields in documents nested deeply in an array. MongoDB can only project fields nested at only a single level when the $ operator is used. As such, this functionality provided is currently not portable to mongoDB

Also, Nodechef supports a new positional operator ($*). See Case 3. The $* positional operator is used to update all elements in an array that match the given condition. The $* operator is also not supported in mongoDB.


This feature is only available from your Nodechef Cloud Search instance. None of the examples provided below will work on a mongodb database. To deploy a cloud search instance, login and navigate to the dashboard. From deployments > deploy cloud search, you can then spin up a cloud search server

Update subdocuments nested more than one level in an array

# Problem: Given the following document in the database, I want to update Dave Gahan's second prescription for Dilaudid from a quantity of 45 to a quantity of 30. Read the issue on github Problem is, using the $ positional locator in Mongodb. This does not find the document embedded multiple levels { "_id" : 1 "name" : "Dave Gahan" "medications" : [ { "id" : 23, "name" : "Dilaudid", "type" : "Rx", "prescriptions" : [ { "id" : 13, "quantity" : 60, "started" : 2009-01-01 }, { "id" : 77, "quantity" : 45, "started" : 2009-02-01 } ] }, { "id" : 41, "name" : "Oxycodone", "type" : "Rx" } ] } # However executing the same update statement in Nodechef cloud search, the update statement succesfully finds and updates the embedded document. db.collection.update( { "_id" : 1, "medications.id" : 23, "medications.prescriptions.id" : 77 }, { $set : { "medications.prescriptions.$.quantity" : 30 } }, false, true )
From the above example, the developer's intent is to update the sub document under the subdocument with the medications.id = 23. An undesirable effect can happen if the medications.prescriptions.id = 77 appears in multiple subdocuments. See below document. The medications.prescriptions.id of 77 appears twice but under different medications.id subdocuments. If the query was to update medications.id = 41, the above solution will update the wrong subdocument as the positional operator finds only the first match. To solve this issue we introduce a new positional operator $$. See solution below.
{ "_id" : 1 "name" : "Dave Gahan" "medications" : [ { "id" : 23, "name" : "Dilaudid", "type" : "Rx", "prescriptions" : [ { "id" : 77, "quantity" : 45, "started" : 2009-02-01 } ] }, { "id" : 41, "name" : "Oxycodone", "type" : "Rx", "prescriptions" : [ { "id" : 77, "quantity" : 45, "started" : 2009-02-01 } ] } ] } db.collection.update( { "_id" : 1, "medications.id" : 41, "medications.prescriptions.id" : 77 }, { $set : { "medications.prescriptions.$$.quantity" : 30 } }, false, true ) # Without the $$ positional operator, the wrong subdocument could be updated. Of course, the $$ operator is not neccesary if the developer generates unique ids for all subdocuments.


Project subdocuments nested more than one level in an array

# Read the issue on meteor forums # Consider the below document, the user wants to publish a single video document nested deeply in sub arrays. # This operation is currently not possible on mongoDB. { _id: "1234", username: 'corvid', playlists: [{ name: 'Learn to Develop Meteor', slug: 'learn-to-develop-meteor-345', videos: [{ title: 'Publications and Subscriptions', description: 'Publish and subscribe data from the server', slug: 'publications-and-subscriptions' }, { title: 'Observable collections', description: 'Observe a live query as it changes', slug: 'observable-collections' }] }, { name: "Let's play Assassin's Creed: Black Flag", slug: 'assassins-creed-black-flag-123', videos: [{ title: 'Part I: You are a pirate!', description: 'What shall we do with a drunken sailor?' }] }] } # To solve this issue in Nodechef cloud search, issue the below command # This will do as the user wishes in the link db.channels.find({ username: 'corvid', 'playlists.videos.title' : 'Publications and Subscriptions' }, { 'playlists.videos.$' : 1 });


Update one or more elements in an array based on a condition

# Problem: Given the following document in the database, I want to update all events.handled # fields in a single update statement. # Read the issue on stackoverflow { "_id" : ObjectId("4d2d8deff4e6c1d71fc29a07"), "user_id" : "714638ba-2e08-2168-2b99-00002f3d43c0", "events" : [ { "handled" : 1, "profile" : 10, "data" : "....." } { "handled" : 1, "profile" : 10, "data" : "....." } { "handled" : 1, "profile" : 20, "data" : "....." } ... ] } # Solution: db.collection.update( { "events.profile" : 10 }, { $set: { "events.$*.handled" : 0 } }, false, true )