I have a collection with documents structured like this
{
_id: 140,
first_list: [
{
_id: ObjectId('623db7e840651f2b7f107ee0'),
second_list: [
{
_id: ObjectId('6241808340651f2b7f108123'),
start_date: ISODate('2022-05-29T22:00:00.000Z'),
end_date: ISODate('2022-06-09T22:00:00.000Z'),
},
{
_id: ObjectId('6241809640651f2b7f108125'),
start_date: ISODate('2022-05-29T22:00:00.000Z'),
end_date: ISODate('2022-06-09T22:00:00.000Z'),
},
{
_id: ObjectId('624180ac40651f2b7f108127'),
start_date: ISODate('2022-05-29T22:00:00.000Z'),
end_date: ISODate('2022-06-09T22:00:00.000Z'),
},
]
}
{
_id: ObjectId('623db7e840651f2b7f107ee2'),
second_list: [
{
_id: ObjectId('6241808340651f2b7f108155'),
start_date: ISODate('2022-05-29T22:00:00.000Z'),
end_date: ISODate('2022-06-09T22:00:00.000Z'),
},
{
_id: ObjectId('6241809640651f2b7f108157'),
start_date: ISODate('2022-05-29T22:00:00.000Z'),
end_date: ISODate('2022-06-09T22:00:00.000Z'),
},
{
_id: ObjectId('624180ac40651f2b7f108159'),
start_date: ISODate('2022-05-29T22:00:00.000Z'),
end_date: ISODate('2022-06-09T22:00:00.000Z'),
},
]
]
}
and I would like to increment all the end_date
s (of all the documents in the collection!) by one hour.
If end_date
was just an item of the outer document, I would have done like this
db.collection.updateMany( {}, [{ $set: { end_date: { $add: ["$end_date", 1 * 60 * 60000] } } }])
but I'm having problems because of the array structure. I tried to read both here and here but couldn't solve my problem yet.
I hope you can help me. Thank you very much.
CodePudding user response:
Here's one way to do it by using a pipeline in the update
.
db.collection.update({
"first_list.second_list.end_date": {
"$exists": true
}
},
[
{
"$set": {
"first_list": {
// rewrite each element of first_list
"$map": {
"input": "$first_list",
"as": "elem1",
"in": {
// keep everything from elem1 and rewrite second_list
"$mergeObjects": [
"$$elem1",
{
"second_list": {
// rewrite each element of second_list
"$map": {
"input": "$$elem1.second_list",
"as": "elem2",
"in": {
// keep all from elem2 and rewrite end_date
"$mergeObjects": [
"$$elem2",
{
"end_date": {
"$dateAdd": {
"startDate": "$$elem2.end_date",
"unit": "hour",
"amount": 1
}
}
}
]
}
}
}
}
]
}
}
}
}
}
],
{"multi": true}
)
Try it on mongoplayground.net.