请注意,文档明确指出,在使用带有更新标识符/名称的函数时,不会触发“pre”中间件:
虽然在使用更新时会将值转换为相应的类型,但以下内容不适用:
- 默认值
- 二传手
- 验证器
- 中间件
如果您需要这些功能,请使用首先检索文档的传统方法。
Model.findOne({ name: 'borne' }, function (err, doc) {
if (err) ..
doc.name = 'jason bourne';
doc.save(callback);
})
因此要么通过 mongooseAPI 采用上述方式,它可以触发中间件(如 desoares 答案中的“pre”)或触发您自己的验证器,例如:
const theOneAndOnlyName = 'Master Splinter';
const UserSchema = new mongoose.Schema({
username: {
type: String,
required: true,
default: theOneAndOnlyName
validate: {
validator: value => {
if(value != theOneAndOnlyName) {
return Promise.reject('{{PATH}} do not specify this field, it will be set automatically');
// message can be checked at error.errors['username'].reason
}
return true;
},
message: '{{PATH}} do not specify this field, it will be set automatically'
}
}
});
或始终使用{ runValidators: true } 形式的附加“选项”参数调用任何更新函数(例如“findByIdAndUpdate”和朋友),例如:
const splinter = new User({ username: undefined });
User.findByIdAndUpdate(splinter._id, { username: 'Shredder' }, { runValidators: true })
.then(() => User.findById(splinter._id))
.then(user => {
assert(user.username === 'Shredder');
done();
})
.catch(error => console.log(error.errors['username'].reason));
您还可以以非标准方式使用验证器功能,即:
...
validator: function(value) {
if(value != theOneAndOnlyName) {
this.username = theOneAndOnlyName;
}
return true;
}
...
这不会抛出“ValidationError”,而是悄悄地覆盖指定的值。它仍然只在使用 save() 或使用指定的验证选项参数更新函数时这样做。