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在两步做同样的事情。

  1. 使用findOne()方法查找结果。
  2. 使用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) { // ... }