如何正确使用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()
)。