如何用Mongoose内置验证器无模型验证多Schema子条目?
问题
我遇到这样的场景:ParentSchema包含一个条目数组,每个条目可适配不同的Schema。每个条目都有一个category字段,用于指明该条目对应的Schema。我的目标是借助Mongoose的内置验证器,根据给定的category来验证每个条目。
请问如何在不为待验证的Schema创建模型的情况下实现这一需求?我能想到的一种方法是创建自定义验证器来检查所有必填字段等,但如果能直接使用Schema自带的内置验证器会非常便捷。
代码示例
const parentSchema = new Schema({ entries: [childSchema] }); const categorySchema = new Schema({ code: { type: String, enum: ["A", "B"] }, name: String }); // 这些Schema中定义了大量必填字段和枚举 // 我希望使用这些Schema定义来验证输入对象,而无需创建模型 const typeADataSchema = new Schema({}); const typeBDataSchema = new Schema({}); const childSchema = new Schema({ category: categorySchema, data: { type: mongoose.Schema.Types.Mixed, enum: [typeADataSchema, typeBDataSchema], validate: [ { validator: function (value) { if (this.category.code === "A") { // 需要完善这个示例`validate`方法 return typeADataSchema.validate(value) } else if (this.category.code === "B") { return typeBDataSchema.validate(value) } else { return false; } } ] } });
解决方案
要在不创建模型的前提下,利用Mongoose内置验证器根据category字段动态验证data,可以直接调用Schema的validate()异步方法,结合自定义验证器的异步能力实现。核心是根据分类匹配对应的Schema,再触发其内置验证规则。
完整代码实现
const mongoose = require('mongoose'); const { Schema } = mongoose; const parentSchema = new Schema({ entries: [childSchema] }); const categorySchema = new Schema({ code: { type: String, enum: ["A", "B"], required: true }, name: String }); // 示例:包含内置验证规则的子Schema const typeADataSchema = new Schema({ aField: { type: String, required: true, enum: ["option1", "option2"] }, anotherAField: { type: Number, min: 0, max: 100 } }); const typeBDataSchema = new Schema({ bField: { type: Date, required: true }, anotherBField: { type: Boolean, default: false } }); const childSchema = new Schema({ category: { type: categorySchema, required: true }, data: { type: mongoose.Schema.Types.Mixed, validate: { validator: async function(value) { let targetSchema; switch(this.category.code) { case "A": targetSchema = typeADataSchema; break; case "B": targetSchema = typeBDataSchema; break; default: return false; } try { // 触发目标Schema的所有内置验证规则 await targetSchema.validate(value, { abortEarly: false }); return true; } catch (err) { // 可选:打印错误详情或自定义错误逻辑 return false; } }, message: ({ instance }) => `数据不符合${instance.category.code}类型的验证规范` } } });
核心要点
- 异步验证支持:Mongoose允许自定义验证器返回Promise,这里用
async/await处理Schema.validate()的异步逻辑。 - 直接复用Schema验证规则:调用Schema的
validate()方法会自动触发其定义的所有内置验证(必填、枚举、数值范围等),无需额外编写自定义校验逻辑。 - 错误控制:
abortEarly: false参数会返回所有验证错误,而非第一个错误,便于调试。 - 动态匹配Schema:通过
this.category.code动态选择对应的验证Schema,实现分类驱动的验证逻辑。
内容的提问来源于stack exchange,提问作者tubular
相关产品推荐
相关产品推荐

