下面是下面User集合中的一个文档示例。
{
"_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")
},
...
]
}
我需要更新"中的所有嵌套文档;learnt_ item";如果";记忆的";字段为false。
更新为:
- "pause_ date"为Null
- "暂停";至False
- 更新"中的ISOdate;next_ review";基于在"0"one_answers"0"之间经过的持续时间;pause_ date"以及当前时间。例如,pause_date是4小时前,那么我想将4小时添加到";next_ review">
我能够实现1&2使用带有arrayFilters的findOneAndUpdate,并且还通过更新";next_ review";具有当前日期的字段,以确保其更新正确。
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)}});
我正在考虑使用$add聚合运算符来增加基于日期的
"learnt_item.$[elem].next_review": {$add: ["$learnt_item.$[elem].next_review","$pause_date"]}
然而,根据文档,arrayFilters不适用于使用聚合管道的更新。
有没有其他更有效的方法可以更新ISOdate?
如果您运行的是MongoDB 4.2或更高版本,您可以使用管道作为更新函数的第二个参数,这样您就可以使用运算符$map
和$cond
来查找属性memorized
等于false
的条目,然后在next_review
日期上加上4天(以毫秒为单位(:
db.collection.update({
"_id": 1
},
[
{
$set: {
"pause_date": null,
"pause": false,
"learnt_item": {
$map: {
input: "$learnt_item",
as: "item",
in: {
$cond: [
{
$eq: [
"$$item.memorized",
false
]
},
{
memorized: "$$item.memorized",
character: "$$item.character",
next_review: {
$add: [
"$$item.next_review",
345600000
]
}
},
"$$item"
]
}
}
},
}
}
],
{
new: true,
});
您可以在此处查看运行示例:https://mongoplayground.net/p/oHh1JWiP8vs