mongoose自定义validation使用2个字段

我想使用mongoose自定义validation来validation,如果endDate大于startDate。 我如何访问startDate值? 当使用this.startDate时 ,它不起作用; 我弄不明白

var a = new Schema({ startDate: Date, endDate: Date }); var A = mongoose.model('A', a); A.schema.path('endDate').validate(function (value) { return diff(this.startDate, value) >= 0; }, 'End Date must be greater than Start Date'); 

diff是比较两个date的函数。

您可以尝试将date标记嵌套在父对象中,然后validation父对象。 比如像这样的东西:

 //create a simple object defining your dates var dateStampSchema = { startDate: {type:Date}, endDate: {type:Date} }; //validation function function checkDates(value) { return value.endDate < value.startDate; } //now pass in the dateStampSchema object as the type for a schema field var schema = new Schema({ dateInfo: {type:dateStampSchema, validate:checkDates} }); 

您可以使用Mongoose 'validate' 中间件来做到这一点,以便您可以访问所有字段:

 ASchema.pre('validate', function(next) { if (this.startDate > this.endDate) { next(new Error('End Date must be greater than Start Date')); } else { next(); } }); 

请注意, next调用报告validation失败时,您必须将validation错误消息包装在JavaScript Error对象中。

对原始问题的接受答案的替代scheme是:

 var mongoose = require('mongoose'), Schema = mongoose.Schema; // schema definition var ASchema = new Schema({ startDate: { type: Date, required: true }, endDate: { type: Date, required: true, validate: [dateValidator, 'Start Date must be less than End Date'] } }); // function that validate the startDate and endDate function dateValidator(value) { // `this` is the mongoose document return this.startDate <= value; } 

我想通过@JohnnyHK(谢谢)通过攻击this.invalidate来扩展这个可靠的答案:

 Schema.pre('validate', function (next) { if (this.startDate > this.endDate) { this.invalidate('startDate', 'Start date must be less than end date.', this.startDate); } next(); }); 

这将保持mongoose.Error.ValidationError错误中的所有validation错误。 有助于保持error handling程序的标准化。 希望这可以帮助。

在validation器中使用“this”对我有效 – 在这种情况下,当检查电子邮件地址的唯一性时,我需要访问当前对象的ID,以便可以将其从count中排除:

 var userSchema = new mongoose.Schema({ id: String, name: { type: String, required: true}, email: { type: String, index: { unique: true, dropDups: true }, validate: [ { validator: validator.isEmail, msg: 'invalid email address'}, { validator: isEmailUnique, msg: 'Email already exists'} ]}, facebookId: String, googleId: String, admin: Boolean }); function isEmailUnique(value, done) { if (value) { mongoose.models['users'].count({ _id: {'$ne': this._id }, email: value }, function (err, count) { if (err) { return done(err); } // If `count` is greater than zero, "invalidate" done(!count); }); } } 

这是我使用的解决scheme(感谢@shakinfree提示):

 var mongoose = require('mongoose'), Schema = mongoose.Schema; // schema definition var ASchema = new Schema({ dateSchema : { type:{ startDate:{type:Date, required: true}, endDate:{type:Date, required: true} }, required: true, validate: [dateValidator, 'Start Date must be less than End Date'] } }); // function that validate the startDate and endDate function dateValidator (value) { return value.startDate <= value.endDate; } module.exports = mongoose.model('A', ASchema);