如何正确使用node.js将新元素推送到mongodb数组

在我的节点应用程序中,我需要将2个元素添加到属于集合“用户”的数组“angular色”中。 我正在使用本机的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个)angular色:'role-1','role-2','role-1,role-2'

显然,我不需要那第三项。 我可以改变什么来避免这种情况?

你有一个collection.update(...)后面的roles.forEach以及一个forEachcallback。 这是导致role-1,role-2的推动,所以删除它!

假设这里的第一行代码实际上正确地“分割”了一个数组,那么你可以将$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); } } ); 

这样就避免了需要使用callback来控制循环,只需在一个操作中完成多个元素的添加即可。

还有$pushAll可以处理“单数”数组元素参数,例如[1,2,3]但是从MongoDB 2.4(现在相当老的版本)开始一般认为它是“弃用的”,赞成使用$each ,这是更有能力的select。

另外请注意.update()不返回已修改的文档,但只是告诉你什么是更新或不。 要在现代驱动程序版本中返回需要.findOneAndUpdate()的文档,或者.findAndModify()操作(以及其他类似操作.findAndModify()的普通调用.findAndModify() )。