Mongoose findOneAndUpdate和runValidators不起作用
我有问题试图让'runValidators'选项工作。 我的用户模式有一个电子邮件字段,其中必须设置为true,但每次有新用户被添加到数据库(使用'upsert'选项),并且电子邮件字段为空时,不会抱怨:
var userSchema = new mongoose.Schema({ facebookId: {type: Number, required: true}, activated: {type: Boolean, required: true, default: false}, email: {type: String, required: true} });
findOneAndUpdate
代码:
model.user.user.findOneAndUpdate( {facebookId: request.params.facebookId}, { $setOnInsert: { facebookId: request.params.facebookId, email: request.payload.email, } }, {upsert: true, new: true, runValidators: true, setDefaultsOnInsert: true }, function (err, user) { if (err) { console.log(err); return reply(boom.badRequest(authError)); } return reply(user); });
我不知道我做错了什么,我只是按照文档: http : //mongoosejs.com/docs/validation.html
在文档中是这样说的:
请注意,在mongoose 4.x中,更新validation程序仅在$ set和$ unset操作上运行。 例如,无论数字的值如何,下面的更新都会成功。
我用$ setreplace$ setOnInsert,但得到相同的结果。
所需的validation器只有在您尝试显式$ unset密钥时才会失败。
这对我来说没有意义,但这是文档所说的。
mongoose在两步做同样的事情。
- 使用
findOne()
方法查找结果。 - 使用
Model.save()
添加字段并保存文档。
这将更新您的文档。
我在做mongoose更新操作之前创build了一个插件来validation所需的模型属性。
插件代码在这里
var mongoose = require('mongoose'); var _ = require('lodash'); var s = require('underscore.string'); function validateExtra(schema, options){ schema.methods.validateRequired = function(){ var deferred = Promise.defer(); var self = this; try { _.forEach(this.schema.paths, function (val, key) { if (val.isRequired && _.isUndefined(self[key])) { throw new Error(s.humanize(key) + ' is not set and is required'); } }); deferred.resolve(); } catch (err){ deferred.reject(err); } return deferred.promise; } } module.exports = validateExtra;
必须从模型中明确地调用方法,所以我build议在更新调用之前将它链接到一个.then
链上。
这里使用的插件
fuelOrderModel(postVars.fuelOrder).validateRequired() .then(function(){ return fuelOrderModel.findOneAndUpdate({_id: postVars.fuelOrder.fuelOrderId}, postVars.fuelOrder, {runValidators: true, upsert: true, setDefaultsOnInsert: true, new: true}) .then(function(doc) { res.json({fuelOrderId: postVars.fuelOrder.fuelOrderId}); }); }, function(err){ global.saveError(err, 'server', req.user); res.status(500).json(err); });
使用这个插件: mongoose-unique-validator
当使用像findOneAndUpdate
这样的方法时,你需要传递这个configuration对象:
{runValidators:true,context:'query'}
即。
User.findOneAndUpdate( { email: 'old-email@example.com' }, { email: 'new-email@example.com' }, { runValidators: true, context: 'query' }, function(err) { // ... }