You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

未设置唯一约束却出现Mongoose Error 11000重复键错误

Error 11000重复键问题排查(未在Mongoose Schema设置唯一约束却触发)

创建包含相同permissions.resource的新角色时触发MongoDB Error 11000重复键错误,但Mongoose Schema中并未给该字段设置唯一约束,问题出在数据库层面已存在针对permissions.resource的唯一索引,和当前代码定义不一致。

问题原因

可能的触发场景:

  • 之前的Schema版本给permissions.resource设置过unique: true,后续代码移除了约束,但数据库里的索引未同步删除
  • 手动在MongoDB Atlas控制台给roles集合的permissions.resource字段创建了唯一索引

解决步骤

1. 手动清理Atlas中的冗余索引

  • 登录MongoDB Atlas控制台,进入目标项目和集群
  • 找到对应数据库,进入roles集合的Indexes标签页
  • 查找键为permissions.resource: 1且Unique属性为true的索引,点击右侧删除按钮确认删除

2. 代码自动排查并删除索引(可选)

如果需要自动化处理,可在项目启动时添加索引检查逻辑:

import RoleModel from './RoleModel';

async function cleanupDuplicateIndex() {
  try {
    const indexes = await RoleModel.collection.indexes();
    const targetIndex = indexes.find(idx => 
      idx.key['permissions.resource'] === 1 && idx.unique
    );
    if (targetIndex) {
      await RoleModel.collection.dropIndex(targetIndex.name);
      console.log('已删除permissions.resource字段的唯一索引');
    }
  } catch (err) {
    console.error('索引清理失败:', err);
  }
}

// 项目启动时执行
cleanupDuplicateIndex();

3. 验证修复

重新尝试创建包含相同permissions.resource的角色,确认Error 11000不再触发。

你的代码参考

BaseSchema

import { Schema } from 'mongoose';

export class BaseSchema extends Schema {
  constructor(schema: any) {
    super(schema, { timestamps: true });
    this.set('toJSON', {
      virtuals: true,
      versionKey: false,
      transform: (doc, ret) => {
        delete ret._id;
      }
    });
  }
}

RoleModel.ts

const RoleModel = new BaseSchema(
  {
    name: {
      type: String,
      required: true,
      unique: true
    },
    permissions: [
      {
        resource: {
          type: Schema.Types.ObjectId,
          ref: 'Resource',
          required: true
        },
        actions: [
          {
            type: Schema.Types.ObjectId,
            ref: 'ActionMethod',
            required: true
          }
        ]
      }
    ]
  }
);

export interface IRole {
  id: string;
  name: string;
  permissions: [
    {
      resource: string | IResource;
      actions: string[] | IActionMethod[];
    }
  ];
}

interface IModel extends IRole, Document {}

export default mongoose.models.Role || mongoose.model<IModel>('Role', RoleModel);

ResourceModel.ts

const ResourceModel = new BaseSchema(
  {
    name: {
      type: String,
      required: true,
      unique: true
    }
  }
);

// export like RoleModel.ts pattern

内容的提问来源于stack exchange,提问作者Jovanka

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 09:35:21