【问题标题】:MongoError: E11000 when trying to update a userMongoError:尝试更新用户时出现 E11000
【发布时间】:2021-07-17 09:14:46
【问题描述】:

所以我有一个节点应用程序,用户可以在其中注册一个帐户(用户名、电子邮件、密码、图标图像)以使用该站点。我创建了一个个人资料页面,其中包含指向编辑表单的链接,以编辑/更新您的用户名、电子邮件和图标图像。但是,每当我尝试更新用户信息时,都会收到 MongoError。

这种情况并非始终如一。有时它会成功更新,所以我不知道是什么导致了问题。

这里是我的代码的 github 链接:https://github.com/P4sc4l94/yelp-camp

我的用户架构:

const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const passportLocalMongoose = require('passport-local-mongoose');

const UserSchema = new Schema({
  email: {
    type: String,
    required: true,
    unique: true
  },
  image: {
    type: String
  }
});

我的用户控制器正在尝试更新信息:

module.exports.editProfile = async (req, res, next) => {
  const {id} = req.params;
  const {username} = req.body.user;
  const {email} = req.body.user;
  const {image} = req.body.user
  console.log(id)
  console.log(username)
  console.log(email)
  console.log(image)
  const user = await User.findOneAndUpdate(id, {username, email, image}, {
    new: true
  });
  user.save();

  console.log(user);
  req.logout();
  req.flash('success', 'Successfully updated profile!')
  return res.redirect(`/login`);
};

【问题讨论】:

    标签: node.js mongodb mongoose error-handling mongoose-schema


    【解决方案1】:

    E11000 是“重复键错误”,意味着您不能在记录上执行“新建”操作,如果您查询的不是id,则可以使用newupsert

    await user.save() 使用时你应该这样做,但这里没有理由这样做

    如果您使用 mongodb ID,您还应该将您的 id 转换为文档 ID,我认为您是为了安全起见

    const mongoose = require('mongoose')
    const { ObjectId } = mongoose.Types
    const { id } = req.params
    const user = await User.findOneAndUpdate({ _id: new ObjectId(id) }, { username, email, image });
    

    【讨论】:

    • 首先,这行得通,所以谢谢你,因为我已经被难住了好几天了!其次,为什么会这样?我有另一个用于创建营地资料的模型,它还有一个编辑表单,您可以更新营地信息。但我不必做所有这些来让它发挥作用。
    • findOneAndUpdate 本身就是一个保存文档的命令,如果您先搜索文档,然后进行更新,最后保存,则只需使用saveawait user.save() 将返回数据库中保存的版本,如果您使用时间戳,则调用保存后时间戳将更新。你得到错误的原因是完全不同的。数据库已经有一个带有您调用的 ID 的文档,当您传递 { new: true } 时,您实际上是在告诉数据库创建它,并且它发生了冲突,因为 ID 是一个索引
    • 作为索引的任何字段在集合(表)中必须是唯一的
    • 我认为 {new: true} 是问题所在,但我被告知 findOneAndUpdate 将返回旧版本,除非我设置 new:true 然后 save()。在那之前我就遇到了错误,但也许是因为我需要像你说的那样将 'id' 设置为文档 ID。
    猜你喜欢
    • 2016-06-15
    • 2021-07-05
    • 2020-10-19
    • 2017-08-27
    • 1970-01-01
    • 2019-07-12
    • 2012-11-10
    • 2015-04-16
    • 1970-01-01
    相关资源
    最近更新 更多