使用Mongoose嵌入子文档时,如何取消其字段的唯一性验证?
问题解决:Mongoose子文档重复字段唯一性验证报错
你的问题出在连续调用.set('code')会覆盖之前的配置,且修改子文档Schema字段的方式不准确,导致role.code的unique约束仍然生效,触发了mongoose-unique-validator的报错。
问题分析
你这段代码里:
const subRole = Role.schema.clone().set('code', {unique: false}).set('code', {index : false});
第二次.set('code', {index : false})会完全覆盖第一次的配置,最终code字段的unique属性还是保留了原Role Schema里的true,所以插入重复role code的Employee时依然会触发唯一性验证。
正确的解决方法
你需要准确修改克隆后的子文档Schema中code字段的属性,同时确保mongoose-unique-validator不会对该字段进行唯一校验。以下是两种可行方案:
方案1:通过path()修改字段配置
const mongoose = require("mongoose"); const uniqueValidator = require("mongoose-unique-validator"); const Role = require("./role"); // 克隆Role Schema const subRole = Role.schema.clone(); // 直接修改code字段的unique和index属性 subRole.path('code').options.unique = false; subRole.path('code').options.index = false; const employeeSchema = mongoose.Schema({ code: { type: String, required: true, unique: true, index: true }, names: { type: String, required: true }, last_names: { type: String, required: true }, role: subRole, // 使用修改后的子文档Schema dui: { type: String, required: true, unique: true, index: true }, nit: { type: String, required: false, unique: true, index: true }, sex: { type: String, required: false }, civil_status: { type: String, required: false }, birthday: { type: Date, required: false }, telephone: { type: String, required: true }, city: { type: String, required: true }, address: { type: String, required: true }, active: { type: Boolean, required: true }, }); employeeSchema.plugin(uniqueValidator); module.exports = mongoose.model("Employee", employeeSchema);
方案2:重新定义子文档字段(更直观)
如果克隆后修改觉得麻烦,也可以直接在Employee Schema里重新定义role的结构,完全脱离原Role Schema的约束:
const mongoose = require("mongoose"); const uniqueValidator = require("mongoose-unique-validator"); const employeeSchema = mongoose.Schema({ code: { type: String, required: true, unique: true, index: true }, names: { type: String, required: true }, last_names: { type: String, required: true }, // 直接定义role子文档结构,不依赖Role Schema role: { code: { type: String, required: true }, // 移除unique和index约束 description: { type: String, required: true } }, dui: { type: String, required: true, unique: true, index: true }, nit: { type: String, required: false, unique: true, index: true }, sex: { type: String, required: false }, civil_status: { type: String, required: false }, birthday: { type: Date, required: false }, telephone: { type: String, required: true }, city: { type: String, required: true }, address: { type: String, required: true }, active: { type: Boolean, required: true }, }); employeeSchema.plugin(uniqueValidator); module.exports = mongoose.model("Employee", employeeSchema);
额外提示
- 如果你不需要Role集合单独存储数据,只是用它的结构作为子文档,方案2会更简洁,避免Schema克隆带来的问题。
- 确保MongoDB中Employee集合的索引里,没有自动创建
role.code的唯一索引(可以通过MongoDB Compass或db.employees.getIndexes()查看),如果有需要手动删除:// 在连接MongoDB后执行 const Employee = require('./employee'); Employee.collection.dropIndex('role.code_1');
内容的提问来源于stack exchange,提问作者Hikaros
相关产品推荐
相关产品推荐

