Home > Enterprise >  Mongoose - Push value to array which is nested in object which is nested in array
Mongoose - Push value to array which is nested in object which is nested in array

Time:01-23

unfortunately I can only find very specific questions on stackoverflow and no exact details in the documentation, so here is a more general example that may help others too.

I just want to add a value to the array (arr) in the object with the "title: 'title3".

{
_id: <id>,
prop1: val1,
prop2: val2,
prop3: [
    {
        title: 'title1',
        arr: ['val1', 'val2', 'val3'],
    },
    {
        title: 'title2',
        arr: ['val1', 'val2', 'val3'],
    },
    {
        title: 'title3',
        arr: ['val1', 'val2', 'val3'], //only update this array
    }
]
}

My current approach looks something like this:

SomeModel.findOneAndUpdate(
    { _id: id, "prop3.title": "title3" },
    {$push: { "prop3.$[].arr": someDoc._id.toString() }}, 
    (err, doc) => {
        if (err) {
            console.log('Error updating doc: ', err);
            resolve(false);
        } else {
            resolve(doc);
        }
    }
);

However, the problem here is that a value is added not only in the array of the object with the title "title3", but everywhere.

How can I add a value exclusively to the array in the object with the title value "title3"? I would also be very grateful for links to documentation explaining this.

CodePudding user response:

This is one solution which may or may not make sense in your full context.

You would have much more luck using the mongoose Document.save() method. Once you have a local copy of the document, you can simply push to the array:

const doc = await SomeModel.findOne({
    _id: id, 
    "prop3.title": "title3" 
});

doc.prop3[3].arr.push(item);
await doc.save();

CodePudding user response:

You can use positional $ operator in this way to do it in a single operation:

Using $ you tell mongo "update the value found in the find object". In this case update only the object where prop3.title is title3.

Note that you are using arrayFilters instead of positional operator.

db.collection.update({
  "_id": 1,
  "prop3.title": "title3"
},
{
  "$push": {
    "prop3.$.arr": "val4"
  }
})

Example here

  •  Tags:  
  • Related