【发布时间】:2020-06-23 18:58:04
【问题描述】:
我正在尝试使用 nodejs 中的 mongoose 更新 MongoDB 中的嵌入式文档。文档被简化如下所示(friendList 中的名称假定是唯一的):
{
"_id" : ObjectId("5eb0617f3aec924ff42249cd"),
"friendList" : [
{
"name" : "Alex",
"flag" : false,
},
{
"name" : "Bob",
"flag" : false,
},
{
"name" : "Caleb",
"flag" : true,
},
{
"name" : "Debbie",
"flag" : false,
}
]
}
我想通过以下方式更新此收藏:
- 接受带有包含
friendList子集的请求正文的 Patch API 和 - 更新嵌套字段
flag。
例如,如果我要使用请求正文从邮递员进行补丁调用:
{
"friendList":[
{
"name":"Alex",
"flag":true
},
{
"name":"Caleb",
"flag":false
},
{
"name":"Debbie",
"flag":false
}
]
}
那么我应该期望我在 MongoDB 中的文档看起来像这样:
{
"_id" : ObjectId("5eb0617f3aec924ff42249cd"),
"friendList":[
{
"name":"Alex",
"flag":true
},
{
"name":"Bob",
"flag":false
},
{
"name":"Caleb",
"flag":false
},
{
"name":"Debbie",
"flag":false
}
]
}
我在 nodejs 上尝试过的是更新整个请求正文:
function updateUser(req){
User.findOneAndUpdate({'_id':req.params._id},req.body,{new:true});
}
替换整个friendList数组:
{
"_id" : ObjectId("5eb0617f3aec924ff42249cd"),
"friendList":[
{
"name":"Alex",
"flag":true
},
{
"name":"Caleb",
"flag":false
},
{
"name":"Debbie",
"flag":false
}
]
}
我也尝试过使用数组运算符,例如$:
function updateUser(req){
User.findOneAndUpdate(
{'_id':req.params._id},
{$addToSet:{
"friendList":{
$each:req.body.friendList}
}
},
{new:true}
);
}
这给了我输出:
{
"_id" : ObjectId("5eb0617f3aec924ff42249cd"),
"friendList" : [
{
"name" : "Alex",
"flag" : false,
},
{
"name" : "Bob",
"flag" : false,
},
{
"name" : "Caleb",
"flag" : true,
},
{
"name" : "Debbie",
"flag" : false,
},
{
"name" : "Alex",
"flag" : true,
},
{
"name" : "Caleb",
"flag" : false,
},
]
}
which $addToSet 在进行比较以检查数组中是否存在值时同时考虑name 和flag。如果我能够在此比较阶段进行拦截以便仅检查 name 字段,它可能会起作用。
我一直在探索$[<identifier>] 和arrayFilter 之类的概念,但似乎无法实现。
【问题讨论】:
-
我没有测试但可能很简单
{$addToSet:{"friendList": req.body.friendList } } -
嗨@WernfriedDomscheit,我试过你的方法,我得到的输出与
{ $addToSet : { "friendList" : { $each : req.body.friendList } }相同,其中name和flag在进行比较时被视为1个实体。