返回

ExpressJS 与 Mongoose 新增文档时“Error: 11000 重复键错误集合”解决方案指南

后端

前言

在使用 Express.js 和 Mongoose 进行数据操作时,我们可能会遇到一个常见的错误:“Error: 11000 重复键错误集合”。这个错误表明我们在新增文档时,遇到了与集合中现有文档 ID 冲突的问题。

原因分析

导致重复 ID 错误的原因主要有以下几点:

  • 默认自动生成 ID: Mongoose 默认会自动为文档生成 ID,如果生成的 ID 与集合中已有的 ID 相同,就会出现冲突。
  • 手动生成 ID: 如果手动设置了文档的 ID,但没有确保其唯一性,也可能导致 ID 重复。
  • 并发操作: 在高并发场景下,多个客户端同时向集合中插入数据,可能会导致 ID 冲突。

解决方案汇总

解决“Error: 11000 重复键错误集合”错误,可以采取以下方法:

  1. 检查手动生成的 ID: 确保手动设置的 ID 具有唯一性,不与现有文档冲突。
  2. 设置自定义 ID 生成器: 通过覆盖 Mongoose 的 _id 属性,使用自定义函数来生成唯一 ID。
  3. 使用 save() 方法而不是 create() save() 方法允许指定 ID,而 create() 方法则会自动生成 ID。
  4. 删除重复文档: 如果发现重复的文档,可以通过查询和删除重复项来解决问题。
  5. 使用唯一索引: 在集合中创建唯一索引,强制确保 ID 的唯一性。

实战指南

设置自定义 ID 生成器

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const userSchema = new Schema({
  name: { type: String, required: true },
  // 自定义 ID 生成器
  _id: { type: String, unique: true, required: true }
});

使用 save() 方法

const user = new User({ name: 'John Doe', _id: 'my-custom-id' });
user.save((err, user) => {
  if (err) {
    console.log(err);
  } else {
    console.log(`新用户已保存,ID 为:${user._id}`);
  }
});

使用唯一索引

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

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

清理重复文档

User.find({ name: 'John Doe' }, (err, users) => {
  if (err) {
    console.log(err);
  } else if (users.length > 1) {
    // 删除重复文档
    for (let i = 1; i < users.length; i++) {
      users[i].remove();
    }
  }
});

结论

在 Express.js 和 Mongoose 中处理“Error: 11000 重复键错误集合”错误,需要对潜在原因有清晰的理解,并采取适当的解决方法。通过设置自定义 ID 生成器、使用 save() 方法、创建唯一索引或清理重复文档,我们可以有效地解决此类问题,确保数据完整性和应用程序的稳定性。