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

时间:2015-07-13 02:49:57

标签: node.js mongodb mongodb-query

在我的节点应用中,我需要向数组添加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'

显然,我不需要第三个条目。 我可以改变什么以避免这种情况?

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(),这是该操作的一般调用(以及其他类似操作)。