我在Node.js后端使用Mongoose,我需要根据条件在文档中更新数组元素的子集。我过去使用save()执行操作,如下所示:
const channel = await Channel.findById(id);
channel.messages.forEach((i) =>
i._id.toString() === messageId && i.views < channel.counter
? i.views++
: null
);
await channel.save();
我想通过使用findByIdAndUpdate来更改此代码,因为它只是一个增量,并且对于我的用例,不需要检索文档。我该怎么做这个手术,有什么建议吗?
当然,channel.messages是正在讨论的数组吗?柜台和均为Number类型
编辑—示例文档:
{
"_id": {
"$oid": "61546b9c86a9fc19ac643924"
},
"counter": 0,
"name": "#TEST",
"messages": [{
"views": 0,
"_id": {
"$oid": "61546bc386a9fc19ac64392e"
},
"body": "test",
"sentDate": {
"$date": "2021-09-29T13:36:03.092Z"
}
}, {
"views": 0,
"_id": {
"$oid": "61546dc086a9fc19ac643934"
},
"body": "test",
"sentDate": {
"$date": "2021-09-29T13:44:32.382Z"
}
}],
"date": {
"$date": "2021-09-29T13:35:33.011Z"
},
"__v": 2
}
你可以试试updateOne
方法如果你不想检索结果文档,
- 同时匹配
id
和messageId
字段条件 - 检查表达式条件,
$filter
迭代messages
数组循环,检查messageId
和views
是否小于counter
则返回结果,$ne
条件检查结果是否为空 $inc
如果查询匹配使用$
位置运算符
views
增加1messageId = mongoose.Types.ObjectId(messageId);
await Channel.updateOne(
{
_id: id,
"messages._id": messageId,
$expr: {
$ne: [
{
$filter: {
input: "$messages",
cond: {
$and: [
{ $eq: ["$$this._id", messageId] },
{ $lt: ["$$this.views", "$counter"] }
]
}
}
},
[]
]
}
},
{ $inc: { "messages.$.views": 1 } }
)
游乐场