5月29日 01:08

Mongoose 数据验证有哪些类型,自定义验证器怎么写?

Mongoose 验证分内置和自定义两类。内置验证器包括:required(必填)、min/max(数值范围)、minlength/maxlength(字符串长度)、enum(枚举值)、match(正则匹配)。自定义验证通过字段的 validate 选项实现,支持同步和异步两种方式。验证默认在 save() 时触发,也可显式调用 validate()validateSync()

追问

unique 是验证器吗?它和 required 有什么本质区别? unique 不是验证器,是索引声明器。它在数据库层创建唯一索引,Mongoose 验证阶段不检查唯一性,只有 MongoDB 写入时才报错。required 才是真正的应用层验证器,在保存前就拦截。所以 unique 的错误是 MongoDB E11000,不是 Mongoose ValidationError。

异步验证器有什么使用场景和注意事项? 典型场景:验证邮箱/用户名是否已存在(需查库)。注意异步验证器中 this 指向当前文档实例,用 this.constructor.findOne() 避免硬编码 Model 名;更新操作默认不触发验证,需设置 runValidators: true

update 操作的验证和 save 有什么区别? save 触发完整验证链(内置+自定义+pre validate钩子);updateOne/updateById 默认跳过验证,需手动传 { runValidators: true },且更新验证只能校验即将修改的字段,无法访问完整文档上下文。

validateBeforeSave 什么时候该设为 false? 仅在数据已通过其他可信渠道验证时使用(如内部迁移脚本、测试数据填充)。生产业务代码不建议跳过,否则脏数据会直接写入数据库。

写段代码

js
const userSchema = new Schema({ email: { type: String, required: true, validate: { validator: async function(v) { const doc = await this.constructor.findOne({ email: v }); return !doc || doc._id.equals(this._id); }, message: '邮箱已被注册' } }, role: { type: String, enum: ['admin', 'user'], default: 'user' } });
标签:Mongoose