简体   繁体   中英

collection update property of embedded document in array

This code uses a loop to $unset the "checked" property of all embedded documents in the "value" array, then $set the one when a condition evaluates to true.
But when the condition is true, the update block failed to update the embedded document by setting a checked: "checked", I know that because meteor:PRIMARY> db.radioOptions.find({}).pretty(); gives the same results before and after.

What am I doing wrong? and how to fix it? Thanks

 meteor:PRIMARY> db.radioOptions.find({}).pretty(); { "_id" : "jXQcsXtedQYotKQXG", "name" : "optionType", "value" : [ { "name" : "1stOption", "caption" : "1st Option" }, { "name" : "2ndOption", "caption" : "2nd Option" } ] } var doc = RadioOptions.findOne({name: obj.name}); if (typeof doc != 'undefined') { doc.value.forEach(function (embdoc) { console.log(embdoc); RadioOptions.update( {name: obj.name, 'value.name': obj.value}, {$unset: {'value.$.checked': ""}} ); if (embdoc.name == obj.value) { console.log(obj.name + " " + obj.value); //obj.value = 1stOption for example RadioOptions.update( {name: obj.name, 'value.name': obj.value}, //obj.name = "optionType" {$set: {'value.$.checked': "checked"}} ); } }) } 

Let's say that is was your objective to set the array element with the name "2ndOption" to "checked" and $unset all other array elements. You would then instead do:

  var doc = RadioOptions.findOne({name: obj.name});
  if (typeof doc != 'undefined') {
    // You have to update every element
    doc.value.forEach(function (embdoc) {
       RadioOptions.update(
           { "_id": doc._id, "value.name": embdoc.name },
           { "$unset": { "value.$.checked": "" } }
       ) 
    });
    // Then just set the one you want
    RadioOptions.update(
       { "_id": doc._id, "value.name": "2ndOption" }, // <-- actually using a variable of course
       { "$set": { "value.$.checked": "checked" } }
    ) 
  }

Now if you had actually read all the responses on the duplicate question you were given for your original question:

How to Update Multiple Array Elements in mongodb

Then you would have seen the response there that mentioned the best way to handle all these mutliple updates was using the "Bulk" API methods in the underlying driver. And also has some useful tips on the general process of updating multiple elements.

On the "server" (not in minimongo) is the best place to to this, and all meteor collections have a .rawCollection() method which returns the collection object from the underlying node native driver.

So the general logic is:

  • Loop all array elements and update to "turn off"
  • Match the element you want to "turn on"

And best done in Bulk rather than responding back and forth for each update.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM