我有一个以下格式的Collection :
[
{
"postId": ObjectId("62dffd0acb17483cf015375f"),
"userId": ObjectId("62dff9584f5b702d61c81c3c"),
"state": [
{
"id": ObjectId("62dffc49cb17483cf0153220"),
"notes": "these are my custom notes!",
"lvl": 3,
},
{
"id": ObjectId("62dffc49cb17483cf0153221"),
"notes": "hello again",
"lvl": 0,
},
]
},
]
我的目标是能够在以下情况下更新和添加此数组中的元素:
- 如果新元素的ID不在
state
数组中,则将新元素推送到数组中 - 如果新元素的ID在
state
数组中,并且其lvl
字段为0,则使用新信息更新该元素 - 如果数组中存在新元素的ID,并且它的
lvl
字段不是0,那么应该不会发生任何事情.我将抛出一个错误,因为我看到没有匹配的文档.
基本上,为了实现这一点,我考虑在upsert中使用findOneAndUpdate
,但我不确定如何告诉查询在lvl
为0时更新状态,或者如果找到匹配项时它大于0,则不执行任何操作.
对于解决(1),这是我能想到的:
db.collection.findOneAndUpdate(
{
"postId": ObjectId("62dffd0acb17483cf015375f"),
"userId": ObjectId("62dff9584f5b702d61c81c3c"),
"state.id": {
"$ne": ObjectId("62dffc49cb17483cf0153222"),
},
},
{
"$push": {"state": {"id": ObjectId("62dffc49cb17483cf0153222"), "lvl": 1}}
},
{
"new": true,
"upsert": true,
}
)
处理这个问题的正确方式是什么?我是否应该将查询拆分成多个查询?
Edit:到目前为止,我已经在多个查询(一个获取文档,然后迭代其状态数组以判断其中是否存在ID,然后在一个普通的if-Else子句中执行(1)、(2)和(3))中完成了此操作)