Mongoose 是一个专门用于操作 MongoDB 数据库的 JavaScript 库。在实际开发过程中,我们经常会使用 Mongoose 来定义数据模型和进行数据校验。尤其是在表单数据校验方面,Mongoose 提供了强大的校验机制。本文将介绍如何解决 Mongoose 中的校验问题,并提供详细的示例代码。
Mongoose 校验机制简介
Mongoose 提供了多种数据类型和校验器,包括字符串、数字、日期、布尔值等基本数据类型以及正则表达式、自定义方法等校验器。每个数据类型都有对应的校验器,可以验证该属性是否符合要求,例如最小值、最大值、长度等。同时,Mongoose 还提供了 pre 和 post 钩子,可以在数据保存之前或之后执行自定义方法。
解决 Mongoose 校验问题的方法
在实际开发中,我们可能会遇到以下校验问题:
- 数据类型错误:例如将字符串类型赋值给数字类型的属性。
- 自定义校验失败:例如需要验证两个属性之间的关系,但是自定义校验器返回 false。
- 校验器无法满足需求:例如需要自定义校验器但是没有找到合适的校验器。
针对以上问题,我们可以采取以下解决方法。
使用 strict
标志
Mongoose 的 strict
标志用于指定是否强制对模型定义以外的属性进行严格检查。如果不设置 strict
标志,则可以随意添加新属性,这些属性将不会被识别或校验。
const schema = new mongoose.Schema({ name: String }, { strict: true }); // 强制执行严格检查
自定义校验方法
如果 Mongoose 中提供的校验器无法满足需求,我们可以自定义校验方法。自定义校验方法需要在 Schema 中的 validate
属性中进行定义。该方法将接收属性值和一个回调函数,如果验证通过则回调函数将不带参数调用,否则返回一个错误对象。
// javascriptcn.com 代码示例 const schema = new mongoose.Schema({ age: { type: Number, validate: { validator: function(v) { return v >= 18; // 自定义校验逻辑 }, message: '您未满 18 岁!' // 校验失败提示信息 } } });
覆盖默认校验器
如果 Mongoose 中的默认校验器无法满足需求,我们可以自定义校验器并通过 SchemaType#validate()
或 SchemaValidator#validate()
方法来覆盖默认校验器。
// javascriptcn.com 代码示例 // 自定义一个 email 校验器 mongoose.Schema.Types.String.checkValid(function(value) { if (typeof value !== 'string') { return false; } const reg = /^([a-z0-9_\\.-]+)@([\da-z\\.-]+)\.([a-z\.]{2,6})$/; return reg.test(value); }, 'Email 格式不正确'); // 在属性定义时使用 const schema = new mongoose.Schema({ email: { type: String, validate: 'email' } }); // 在整个 Schema 中使用 const schema = new mongoose.Schema({ email: { type: String, required: true } }, { validateBeforeSave: false }); // 忽略保存之前的校验 schema.path('email').validate('id', function(v) { // 自定义校验逻辑 return this.confirmEmail === v; }, '两次输入的电子邮件不一致');
示例代码
以下示例代码展示了如何解决 Mongoose 中的校验问题。
// javascriptcn.com 代码示例 const mongoose = require('mongoose'); const Schema = mongoose.Schema; // 使用 strict 标志 const userSchema = new Schema({ name: String }, { strict: true }); const User = mongoose.model('User', userSchema); // 自定义校验方法 const carSchema = new Schema({ brand: { type: String, validate: { validator: function(v) { return ['BMW', 'Mercedes-Benz', 'Porsche'].includes(v); // 自定义校验逻辑 }, message: '不支持该品牌的汽车' // 校验失败提示信息 } } }); const Car = mongoose.model('Car', carSchema); const car = new Car({ brand: 'Audi' }); car.validate(function(error) { console.log(error); // 预期输出:{ ValidationError [ '不支持该品牌的汽车' ] } }); // 覆盖默认校验器 mongoose.Schema.Types.String.checkValid(function(value) { if (typeof value !== 'string') { return false; } const reg = /^([a-z0-9_\\.-]+)@([\da-z\\.-]+)\.([a-z\.]{2,6})$/; return reg.test(value); }, 'Email 格式不正确'); const newSchema = new Schema({ email: { type: String, required: true } }, { validateBeforeSave: false }); // 忽略保存之前的校验 newSchema.path('email').validate('id', function(v) { return this.confirmEmail === v; // 自定义校验逻辑 }, '两次输入的电子邮件不一致'); const New = mongoose.model('New', newSchema); const newUser = new New({ email: 'abc@123.com', confirmEmail: 'abc@1234.com' }); newUser.validate(function(error) { console.log(error); // 预期输出:{ ValidationError [ '两次输入的电子邮件不一致' ] } });
总结
本文介绍了如何解决 Mongoose 中的校验问题,共提供了三种方法:使用 strict
标志、自定义校验方法、覆盖默认校验器。通过学习本文,您可以更好地理解 Mongoose 的校验机制,并掌握解决校验问题的方法。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/653b299f7d4982a6eb57e2f4