通常,您可以使用猫鼬验证,但由于需要异步结果(对现有名称的db查询)并且验证器不支持promise(据我所知),因此需要创建自己的函数并传递回调。这是一个例子:
var mongoose = require('mongoose'), Schema = mongoose.Schema, ObjectId = Schema.ObjectId;mongoose.connect('mongodb://localhost/testDB');var UserSchema = new Schema({ name: {type:String}});var UserModel = mongoose.model('UserModel',UserSchema);function updateUser(user,cb){ UserModel.find({name : user.name}, function (err, docs) { if (docs.length){ cb('Name exists already',null); }else{ user.save(function(err){ cb(err,user); }); } });}UserModel.findById(req.param('sid'),function(err,existingUser){ if (!err && existingUser){ existingUser.name = 'Kevin'; updateUser(existingUser,function(err2,user){if (err2 || !user){ console.log('error updated user: ',err2);}else{ console.log('user updated: ',user);} }); } });更新:更好的方法
前置钩似乎是停止保存的更自然的地方:
UserSchema.pre('save', function (next) { var self = this; UserModel.find({name : self.name}, function (err, docs) { if (!docs.length){ next(); }else{ console.log('user exists: ',self.name); next(new Error("User exists!")); } });}) ;更新2:异步自定义验证器
看起来猫鼬现在支持异步自定义验证器,因此这可能是自然的解决方案:
var userSchema = new Schema({ name: { type: String, validate: { validator: function(v, cb) { User.find({name: v}, function(err,docs){ cb(docs.length == 0); }); }, message: 'User already exists!' } } });


