Below is an example of a document in a User collection below.
{
"_id" : 1,
"username" : bob,
"pause" : true,
"pause_date" : ISODate("2021-07-16T07:13:48.680Z"),
"learnt_item" : [
{
"memorized" : false,
"character" : "一",
"next_review" : ISODate("2021-07-20T11:02:44.979Z")
},
{
"memorized" : false,
"character" : "二",
"next_review" : ISODate("2021-07-20T11:02:44.979Z")
},
...
]
}
I need to update all the nested document in "learnt_item" if the "memorized" field is false.
The updates are:
- "pause_date" to Null
- "pause" to False
- Update the ISOdate in "next_review" based on the duration that has passed between "pause_date" and the current time. E.g. pause_date is 4 hours ago, then I want to add 4 hours to the "next_review"
I was able to achieve 1 & 2 using findOneAndUpdate with arrayFilters and also tested no.3 by updating the "next_review" field with a current date to make sure it is updating correctly.
User.findOneAndUpdate({"_id": req.user._id},
{$set:{"learnt_item.$[elem].next_review": DateTime.local(),"pause_date": null, "pause": value }},
{new:true, arrayFilters: [{"elem.memorized": false}]}).exec((err, doc) =>{if (err){res.send(err)} else {res.send(doc)}});
I was thinking of using the $add aggregation operator to increase the date base
"learnt_item.$[elem].next_review": {$add: ["$learnt_item.$[elem].next_review","$pause_date"]}
However, according to the documentation, arrayFilters is not available for updates that use an aggregation pipeline.
Is there another way more efficient way that I can update the ISOdate?