如何在Mongoose中基于其他字段验证并设置字段值
实现根据type验证并自动设置status的方法
一、添加自定义验证器校验status值
直接在status字段中加入自定义验证逻辑,确保提交的status和type严格匹配,同时明确标记status为必填项(因为需求里两个字段都必填,无需之前的条件判断):
const bottle: Schema = new Schema({ type: { type: String, required: true, enum: ['gas', 'noGas'], }, status: { type: String, enum: ['good', 'bad'], required: true, validate: { validator: function(this: IBottle, value: string) { // 根据当前type校验status是否符合规则 if (this.type === 'gas') { return value === 'good'; } else if (this.type === 'noGas') { return value === 'bad'; } return false; }, message: props => `当type为${props.instance.type}时,status必须为${props.instance.type === 'gas' ? 'good' : 'bad'}` } } });
二、自动设置status值(可选)
如果希望无需手动传入status,由系统根据type自动赋值,可以借助Mongoose的前置中间件实现:
1. 保存文档时自动设置
添加pre('save')钩子,在保存前根据type赋值status:
bottle.pre('save', function(next) { if (this.type === 'gas') { this.status = 'good'; } else if (this.type === 'noGas') { this.status = 'bad'; } next(); });
2. 更新文档时自动设置
针对findOneAndUpdate这类更新操作,需要单独处理,操作更新对象来设置status:
bottle.pre('findOneAndUpdate', async function(next) { const update = this.getUpdate() as Partial<IBottle>; // 如果更新时修改了type,直接根据新type设置status if (update.type) { update.status = update.type === 'gas' ? 'good' : 'bad'; } else { // 如果未修改type,查询当前文档的type来同步status(按需选择) const doc = await this.model.findOne(this.getQuery()); if (doc) { update.status = doc.type === 'gas' ? 'good' : 'bad'; } } this.setUpdate(update); next(); });
注意事项
- 若启用自动赋值中间件,仍建议保留status的必填验证,避免中间件未触发的异常情况。
- 中间件需在schema定义完成后挂载,确保能正确绑定到模型上。
内容的提问来源于stack exchange,提问作者PlayHardGoPro
相关产品推荐
相关产品推荐

