Mongoose – 模式对象的asynchronousvalidation

我想确定如何做一个Mongoose模式的asynchronousvalidation – 特别是在这种情况下的用户名。 TMK,以确保用户名是唯一的,我们必须手动查询数据库,看看是否已经存在相同的用户名。 这是一个asynchronous查询。 然而,对每个模式项目使用'validate:'属性的方法似乎要求同步validationfunction。 换句话说,这一行:

validation:[validation.usernameValidator,'不是有效的用户名']

似乎要求usernameValidator是同步的,问题是我需要它是asynchronous的,由于上述原因。

所以,我有一个像这样的用户Mongoose模式:

var validation = { usernameValidator: function (candidate) { return true; }, passwordValidator: function (candidate) { return true; } }; userSchema = mongoose.Schema({ username: { type: String, isUnique: true, required: true, validate: [validation.usernameValidator, 'not a valid username'] }, passwordHash: { type: String, required: true, validate: [validation.passwordValidator, 'not a valid password'] }, email: { type: String, isUnique: true, required: true, validate: [validation.emailValidator, 'not a valid email address'] } }); userSchema.pre('save', function (next) { var self = this; if (!self.isModified('passwordHash')) { return next(); } bcrypt.hash(self.passwordPreHash, SALT_WORK_FACTOR, function (err, hash) { if (err) { return next(err); } else if(hash == null){ return next(new Error('null/undefined hash')); } else { self.passwordHash = hash; next(); } }); }); //is the following function my best bet? userSchema.path('username').validate(function (value, respond){ this.findOne({ username: value }, function (err, user){ if(user) respond(false); }); }, 'This username has been already registered'); 

是我唯一的select,省略validation.usernameValidator方法,并用userSchema.path('用户名')validation用户名。

mongoose应该处理这个,只要你在该字段上指定unique: true

例如

 userSchema = mongoose.Schema({ username: { type: String, unique: true, required: true }, passwordHash: { type: String, required: true }, email: { type: String, unique: true, required: true } }); 

加成:

Mongoose将声明一个唯一的索引,只要你在你的模式中指定了这个(如上面的例子中所做的那样)。 这样可以避免必须查询mongodb来查看是否有其他文档具有相同值的字段。 你可以在这里阅读。

如果您想了解更多关于他们的行为的信息,可以在这里阅读更多关于mongodb的唯一索引。

注意:如果提供非唯一值,validation错误将不会被抛出。 有关详细信息,请参阅mongoose文档。