未设置唯一约束却出现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
相关产品推荐
相关产品推荐

