0

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 e.g. findOneAndUpdate and if so, how?

1 Answer 1

1

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);
    }
);
Sign up to request clarification or add additional context in comments.

1 Comment

Sorry, I think I was a bit unclear. What I'm looking for is a generic way of updating the document in question. So basically, what would be the equivalent of the code I'm currently using for updating the document using e.g. findOneAndUpdate?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.