在我的节点应用中,我需要向数组添加2个元素'角色'属于集合'用户'。 我使用的是原生的mongodb驱动程序。 这是我的代码:
MongoClient.connect(url, function (err, db) {
if (err) {
console.log('Unable to connect to the mongoDB server. Error:', err);
} else {
console.log('Connection established to', url);
var collection = db.collection('users');
var roles = req.body.requestedRoles.split(',');
roles.forEach(function(role){
collection.update(
{
email: req.body.userEmail
},
{
$push: { roles: role }
},
{upsert: true},
function(err, result) {
if (err) {
console.log('err: ' + err);
}
else {
console.log('update result: ' + result);
}
}
);
});
collection.update(
{
email: req.body.userEmail
},
{
$push: { roles: req.body.requestedRoles }
},
{upsert: true},
function(err, result) {
if (err) {
console.log('err: ' + err);
}
else {
console.log('update result: ' + result);
}
}
);
}
});
req.body.requestedRoles包含" role-1,role-2"
当此代码运行时,我最终会得到以下3个(而不是2个)角色:' role-1',' role-2',' role- 1,角色2'
显然,我不需要第三个条目。 我可以改变什么以避免这种情况?
答案 0 :(得分:1)
collection.update(...)
之后的roles.forEach
以及forEach回调中的role-1,role-2
。这导致hidden-print
的推送,所以删除它!
答案 1 :(得分:1)
假设这里的第一行代码实际上是正确的"分裂"然后,您只需将$each
修饰符添加到$push
:
var roles = req.body.requestedRoles.split(',');
collection.update(
{ "email": req.body.userEmail },
{ "$push": { "roles": { "$each": roles } } },
{ "upsert": true },
function(err, result) {
if (err) {
console.log('err: ' + err);
}
else {
console.log('update result: ' + result);
}
}
);
这避免了需要使用回调来控制循环,只需将多个元素添加到数组中,因为它可以在单个操作中完成。
还有$pushAll
可以使用" singular"数组元素参数,例如[1,2,3]
,但这通常被认为是"已弃用"从MongoDB 2.4(现在很旧的版本)开始,支持使用$each
,这是更有能力的替代方案。
另请注意,.update()
不会返回修改后的文档,只会告诉您更新的内容。要在现代驱动程序版本中返回您想要的文档.findOneAndUpdate()
或.findAndModify()
,这是该操作的一般调用(以及其他类似操作)。