首页 > 解决方案 > 使用另一个集合中的 _id 时出现重复键错误

问题描述

到目前为止,我有 2 个系列。
第一个是“用户”集合(效果很好),另一个是“房间”集合(都是为聊天应用程序创建的)。

我希望每个房间都有一个“用户”数组,其中包含该房间中每个用户的 user._id,
意味着我应该能够将相同的 user._id(来自用户集合)放在每个房间中房间对吗?

在“users”数组中使用 2 个 user._ids 成功创建房间后,
我尝试使用我在第一个房间中使用的 user._ids 创建另一个房间。
然后我得到了这个错误:

MongoError:E11000 重复键错误集合:ratchat.rooms 索引:users_1 重复键:
{用户:“5fe08d452f34530e641d8f8c”}

在使用调试器检查后,我发现只有当我使用另一个房间的“用户”数组中已经使用的 user._id 时才会发生错误。
我能想到的唯一可能导致这个问题的是房间模式,
也许我在阅读文档时错过了一些东西......

起初我的房间模式看起来像这样:

  const roomSchema = new mongoose.Schema({
  users: [String],
  hasLeft: [String],
  isGroup: { type: Boolean, default: false },
  },
});
const Room = mongoose.model("Room", roomSchema);

然后我想也许 mongoDB 需要知道 users 数组中的 ObjectIds 只是对另一个集合的引用:

  const roomSchema = new mongoose.Schema({
  users: [{ type: mongoose.Schema.Types.ObjectId, ref: "User" }],
  hasLeft: [String],
  isGroup: { type: Boolean, default: false },
  },
});
const Room = mongoose.model("Room", roomSchema);

到目前为止没有运气...

标签: javascriptnode.jsmongodbmongoosemongoose-schema

解决方案


{自动索引:假}

经过研究,我找到了这个错误的原因:
mongoose 自动创建索引
这不仅是重复错误问题,而且会在以后的生产中造成显着的性能影响。

根据mongoose docs,您可以通过将架构的 autoIndex 选项设置为 false 来轻松禁用此行为,或者通过将选项 autoIndex 设置为 false 来在连接上全局禁用此行为。

  mongoose.connect('mongodb://user:pass@localhost:port/database', { autoIndex: false });
  // or
  mongoose.createConnection('mongodb://user:pass@localhost:port/database', { autoIndex: false });
  // or
  animalSchema.set('autoIndex', false);
  // or
  new Schema({..}, { autoIndex: false });

在重试之前不要忘记删除整个集合

因为集合已经被索引,完全清空它是行不通的。
您必须删除整个集合。


推荐阅读