简体   繁体   中英

How to update a document having an array of arrays in MongoDB with Mongoose?

Given the following schema:

const item = {
   _id: false,
   amount: { type: Number, required: true },
};

const item_schema = new Schema({ item_history: [item] });

const parent_schema = new Schema({
     ...

     items: [item_schema],

     ...
   })

and this document in the database

{
   ...

   items: [{ _id: 1, item_history: [{ amount: 10 }] }]

   ...
}

Let's say I want to update this document with these items:

const changed_or_new_items = [{ _id: 1, amount: 20 }, { amount: 30 }];

Which should result in this object in the database:

{
   ...

   items: [{ _id: 1, item_history: [{ amount: 10 }, { amount: 20}] }, 
           { _id: 2, item_history: [{ amount: 30 }] }]

   ...
}

This is how I currently update the document:

const parent = await Parent.findOne(some_query).exec();

changed_or_new_items.forEach(item => {
  if (!item._id) {
    parent.items.push({ item_history: [item] });
  }
  else {
    const item_doc = parent.items.id(item._id);
    item_doc.item_history.push(_.omit(item, '_id'));
  }
});
await parent.save();

Would the above be possible to achieve using an update operation eg findOneAndUpdate and if so, how?

You can use findOneAndUpdate with arrayFilters as:

Parent.findOneAndUpdate(
    { 'items._id': 1 },
    { '$set': { 'items.$.item_history.$[element].amount': 30 } },
    { 
        'arrayFilters': [ {'element.amount': 20} ],
        'new': true,
        'upsert': true
    }, (err, updatedParent ) => {
        if (err) res.status(400).json(err);
        res.status(200).json(updatedParent);
    }
);

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