【问题标题】:FindOneAndUpdate with the model in mongooseFindOneAndUpdate 与猫鼬模型
【发布时间】:2018-07-15 12:18:04
【问题描述】:

如果现有文档不存在,我尝试了两种方法来覆盖它。

第一种方式

此代码不起作用并在每次更新时抛出此错误:

错误: *对文档 {_id: ObjectId('***') , ...} 应用更新后,发现(不可变)字段 '_id'改成_id:ObjectId('***78')"*

exports.loginUser = function (req, res) {
var newUser = new userModel(req.body);
userModel.findOneAndUpdate({email: req.body.email}, newUser ,{ new: true, 

upsert:true, setDefaultsOnInsert: true }, function (err, userUpdate) {

return res.json(userUpdate);

}

第二条路

直接插入请求body 效果很好。但我不想那样做,因为body 可以有垃圾:

exports.loginUser = function (req, res) {
var newUser = new userModel(req.body);
userModel.findOneAndUpdate({email: req.body.email}, req.body ,{ new: true, 

upsert:true, setDefaultsOnInsert: true }, function (err, userUpdate) {

return res.json(userUpdate);

}

那么任何人都可以建议我如何使用模型而不是请求正文来做findOneAndUpdate

【问题讨论】:

    标签: node.js mongodb express mongoose


    【解决方案1】:

    使用.update()方法:

    var newUser = new userModel(req.body);
    
    newUser.update(newUser, { upsert:true, setDefaultsOnInsert: true }, function (err) {
        if (err) {
            console.log(err);
            return res.json('Cannot save user');
        }
    
        res.json(newUser);
    });
    

    无需使用new:true 选项,因为newUser 将始终包含更新或插入的文档

    【讨论】:

    • 如果我使用保存,那么我会收到“重复键错误索引:”错误,因为根据猫鼬文档保存确实考虑了 _id。如果它存在,那么它将给出重复错误。
    • 还有另一种方法可以通过在模型实例上调用更新方法来做到这一点,它也可以接受模型实例,不仅是对象,请参阅我的更新答案
    • userModel.update({email: req.body.email}, {fullName: 'rt'}, {upsert: true, setDefaultsOnInsert: true}, function (err, userUpdate) { if (err) { console.log(err); return res.json('Cannot save user'); } res.json(newUser); }); 当我尝试更新单个字段时它运行良好,但如果我尝试更新整个模型对象则不起作用。在我的情况下,这是 newUser 变量
    • 是的,如果您尝试更新整个文档,它会起作用,在我的示例中,我使用了模型实例 newUser.update 而不是您使用的模型 userModel.update,请尝试一下
    • 我尝试过这种方式来更新模型和集合,但收到错误提示 duplicate key error index: sample2.user.$email_1 dup key
    【解决方案2】:

    你不应该使用new,因为这会创建一个新的_id,所以你应该这样做:

    exports.loginUser = function(req, res) {
        var newUser = req.body; // here remove the new
        userModel.findOneAndUpdate(
            { email: req.body.email },
            newUser,
            { new: true, upsert: true, setDefaultsOnInsert: true },
            function(err, userUpdate) {
                return res.json(userUpdate);
            }
        );
    }
    

    【讨论】:

    • 我已经以第二种方式给出了这个有问题的解决方案,但我想避免这种情况,因为我想将它与他们在某些条件下检查的模型(如必填字段)进行映射。
    • 2way 始终使用new userModel(req.body)
    猜你喜欢
    • 2017-10-05
    • 2021-09-25
    • 2020-11-13
    • 2013-06-19
    • 2013-02-13
    • 1970-01-01
    • 1970-01-01
    • 2015-09-15
    • 2015-10-26
    相关资源
    最近更新 更多