【问题标题】:Mongoose MODEL update() vs save()猫鼬模型更新()与保存()
【发布时间】:2019-03-22 15:52:30
【问题描述】:

有一个question about update() vs save(),但它针对的是一些不同的东西(我猜,纯粹与mongoose.Schema 方法相关,但与实际文档无关)

我有以下场景,用户登录网站:

  • 我需要加载文档(通过userModel.email找到它)
  • 检查 userModel.password 哈希是否与收到的内容匹配
  • 更新userModel.lastLogin时间戳
  • 将授权事件附加到userModel.myEvents[]数组

所以我想知道 - 正确的方法是什么?

1)

let foundUser = userModel.findOne({ email: recievedEmail });
if(foundUser.password != recievedPassword)
    return res.status(400).json({e: "invalid pass"});
foundUser.lastLogin = new Date();
foundUser.myEvents.push(authEvent)
foundUser.save();

2)

let foundUser = userModel.findOne({ email: recievedEmail });
if(foundUser.password != recievedPassword)
    return res.status(400).json({e: "invalid pass"});
foundUser.update({
    $push: { myEvents: authEvent },
    $set: { lastLogin: new Date() }
});
foundUser.save();

3)

let foundUser = userModel.findOne({ email: recievedEmail });
if(foundUser.password != recievedPassword)
    return res.status(400).json({e: "invalid pass"});
userModel.updateOne({_id: foundUser._id}, {$push: ...
// seems no save is required here?

4)

// I am doing it wrong, and you have faster/higher/stronger variant?

【问题讨论】:

    标签: node.js mongodb mongoose passwords authorization


    【解决方案1】:

    首先,在使用 foundUser.update() 方法时,不需要调用 foundUser.save()。

    而且,上述所有方法几乎同样有效,因为对数据库进行了两次调用。因此,这取决于您的个人喜好。

    而且,只需一次调用数据库的另一种方法可以以这种方式执行:-

    let foundUser = await userModel.findOneAndUpdate(
     { email: recievedEmail, password: hashedPassword },
     { $set: { lastLogin: new Date() }, $push: { myEvents: authEvent } }
    );
    

    在此方法中,如果存在具有给定电子邮件和密码的用户,则该用户将被更新,并且相应的更新文档将在foundUser 变量中返回。所以你不必对密码进行额外的检查:如果findOneAndUpdate()返回一个文档,这意味着密码和电子邮件匹配。您只需在返回的文档上检查 null 或 undefined 是否不匹配。

    【讨论】:

    • “首先,当你使用 foundUser.update() 方法时,你不需要调用 foundUser.save()。” 在这种情况下没有更新在数据库中,我试过了。
    • 它返回一个承诺。等结果吗?
    • 这不是必需的。我使用 Robo3T 并看到它从未更新(不保存)。因为 foundUser 是一个文档,而不是一个模型。但是,您提出了更好的方法,所以这就是答案。
    • Robo3t 不使用猫鼬。你不能在 robo3t 中执行 mongoose 命令
    • 您也可以通过在查询末尾附加 .exec() 来执行查询。如果 findOneAndUpdate 返回一个文档,则表示密码和电子邮件匹配。因此,只需检查返回文档上的 null 或 undefined 是否不匹配。
    猜你喜欢
    • 1970-01-01
    • 2020-09-05
    • 2015-04-10
    • 2017-11-01
    • 1970-01-01
    • 2013-02-11
    • 2015-10-21
    • 2015-01-14
    • 1970-01-01
    相关资源
    最近更新 更多