如何在使用Mongoose中更新嵌套对象

时间:2018-07-12 11:42:17

标签: javascript node.js mongodb mongoose nosql

假设给定User上的当前数据是

{
            accountType:12,
            address:{
                address1:"uk1"
            },
            shareDealing:{
                providers:{
                    uk:{
                        accountProviderId:"12",
                        accountProviderName: "as",
                    }
                }
            }
        }

然后,我想插入以下数据来更改所有字段,只是我不包括shareDealing.providers.uk.accountProviderName,因为它没有更改,我希望其中一个保留在用户文档中

所以我要更新的数据将是

user = {
            accountType:22,
            address:{
                address1:"aaaaaa"
            },
            shareDealing:{
                providers:{
                    uk:{
                        accountProviderId:"333333333333",
                    }
                }
            }
        };

所以我运行了以下代码

User.update(searchBy, user, {upsert:true}).then((data) =>{

            if(data === null) throw new AppError(400,"User Not Found",5);

            res.json({ message: 'User Updated', data: req.body });
            logger.debug("Saved Data : Using  "+ JSON.stringify(searchBy) +" record: "+ JSON.stringify (data));
        }).catch( (error) => {
            new Errorhandler( new AppError(400,error)).display(req,res);
        });

我的问题

当我进行更新时,更新的用户记录没有accountProviderName: "as",因为它认为最新的JSON应该是完整的用户记录。

是否有一种方法可以更新所有更改的字段,但仅通过更新保留以前的非接触字段?

我知道一种解决方法正在使用以下代码,但(也许是一厢情愿),我希望在更新功能链之外对用户记录进行验证并为其分配数据。

不得不两次调用数据库来一次发现另一个调用来进行更新,这感觉有些过头了

User.findById(searchBy).then((fetchedUser) => {
            if(fetchedUser === null) throw new AppError(400,"User Not Found",5);

            // In my ideal world i would prefer to validate and assign data outside this chain
            return functionThatValidatesAndAssignsDataToTheUser(fetchedUser,user);
        }).then((model) => {
            return model.save();
        }).then((updatedModel) => {
            res.json({
                msg: 'model updated',
                updatedModel
            });
        }).catch((err) => {
            res.send(err);
        });

2 个答案:

答案 0 :(得分:2)

我认为您应该在更新查询中使用$set。请参考下面的查询,它已经过测试,可以根据需要进行适当的修改

db.agreements.update({},{ $set:
  {
    "accountType":45,
    "address.address1":"india",
    "shareDealing.providers.uk.accountProviderId":984,
    }

})

答案 1 :(得分:-1)

您应该在$set中使用Model.update。如果需要,请按this链接提供示例,以解决问题。