我在npm:{/ p>中使用此模式与mongoose 3.0.3
var schema = new Schema({
_id: Schema.ObjectId,
email: {type: String, required: true, unique: true}
});
如果我尝试保存已经在db中的电子邮件,如果省略ValidationError
字段,我希望得到required
。但事实并非如此,我得到MongoError: E11000 duplicate key error index
。
哪个不是验证错误(即使我删除了unique:true也会发生)。
知道为什么吗?
答案 0 :(得分:26)
我更喜欢把它放在路径验证机制中,比如
UserSchema.path('email').validate(function(value, done) {
this.model('User').count({ email: value }, function(err, count) {
if (err) {
return done(err);
}
// If `count` is greater than zero, "invalidate"
done(!count);
});
}, 'Email already exists');
然后它会被包裹到ValidationError
中,并在您致电validate
或save
时作为第一个参数返回。
答案 1 :(得分:11)
这是预期的行为
unique: true
相当于在mongodb中设置索引,如下所示:
db.myCollection.ensureIndex( { "email": 1 }, { unique: true } )
要使用Mongoose进行这种类型的验证(Mongoose称这种复杂的验证 - 即 - 您不仅仅是断言值是一个数字),您需要连接到预存事件:
mySchema.pre("save",function(next, done) {
var self = this;
mongoose.models["User"].findOne({email : self.email},function(err, results) {
if(err) {
done(err);
} else if(results) { //there was a result found, so the email address exists
self.invalidate("email","email must be unique");
done(new Error("email must be unique"));
} else {
done();
}
});
next();
});
答案 2 :(得分:0)
我对批准的答案有一些疑问。即:
this.model('User')
对我不起作用。done
不能正常工作。我通过以下方式解决了这些问题:
UserSchema.path('email').validate(async (value) => {
const emailCount = await mongoose.models.User.countDocuments({email: value });
return !emailCount;
}, 'Email already exists');
我使用async/await
这是个人喜好,因为它更整洁:https://javascript.info/async-await。
如果我做错了事,请告诉我。
答案 3 :(得分:0)
仅响应json
try {
let end_study_year = new EndStudyYear(req.body);
await end_study_year.save();
res.json({
status: true,
message: 'បានរក្សាទុក!'
})
}catch (e) {
res.json({
status: false,
message: e.message.toString().includes('duplicate') ? 'ទិន្នន័យមានរួចហើយ' : e.message.split(':')[0] // check if duplicate message exist
})
}