I've been struggling to get my around how to update a object in a nested array with a particular id. I've attempted to implement $set as shown below. I want to be able to update the task with an _id of 62ff74bfe80b11ade2d34455 with the data from the request body.
{
"_id": "62fa5aa25778ec97bc6ee231",
"user": "62f0eb5ebebd0f236abcaf9d",
"name": "Marketing Plan",
"columns": [
{
"name": "todo",
"_id": "62fa5aa25778ec97bc6ee233",
"tasks": [
{ ====> here
"title": "Task Four",
"description": "This is task four",
"subtasks": [
{
"name": "wash dshes",
"completed": false,
"_id": "62ff74bfe80b11ade2d34456"
},
{
"name": "do homework",
"completed": false,
"_id": "62ff74bfe80b11ade2d34457"
}
],
"_id": "62ff74bfe80b11ade2d34455"
}
]
},
{
"name": "doing",
"_id": "62fa5aa25778ec97bc6ee234",
"tasks": []
},
{
"name": "done",
"_id": "62fa5aa25778ec97bc6ee235",
"tasks": []
}
],
"__v": 0
}
const updatedTask = await Board.findOneAndUpdate(
{
"columns.tasks._id": req.params.id,
},
{ $set: { "columns.$.tasks": req.body } },
{ new: true }
);
CodePudding user response:
You can use the positional operator in combination with an arrayfilter. Here's an example how you'd update a specific field of the relevant task:
db.collection.update({
"columns.tasks._id": req.params.id
},
{
"$set": {
"columns.$[].tasks.$[t].title": "it works"
}
},
{
"arrayFilters": [
{
"t._id": req.params.id
}
]
})
You can also try this on mongoplayground.
If you're looking for a way to replace the matching task object itself you can do:
db.collection.update({
"columns.tasks._id": req.params.id
},
{
"$set": {
"columns.$[].tasks.$[t]": req.body
}
},
{
"arrayFilters": [
{
"t._id": req.params.id
}
]
})