为什么Mongoose不会在更新时验证?

时间:2013-03-26 01:51:59

标签: mongoose

我有这段代码

var ClientSchema = new Schema({
  name: {type: String, required: true, trim: true}
});

var Client = mongoose.mode('Client', ClientSchema);

使用express,我使用此代码创建一个新客户端

var client = new Client(req.body);
client.save(function(err, data) {
  ....
});

如果我在表单上留下名称字段为空,则mongoose不允许创建客户端,因为我在架构上按需要设置它。另外,如果我在名称前后留空格,mongoose会在保存前删除该空格。

现在,我尝试使用此代码更新客户端

var id = req.params.id;
var client = req.body;
Client.update({_id: id}, client, function(err) {
  ....
});

它允许我更改名称,但如果我在表单上将其留空,则mongoose不会验证并保存一个空名称。如果我在名称前后添加空格,则用空格保存名称。

为什么mongoose会在保存时验证,但不会在更新时验证?我是以错误的方式做到的?

mongodb:2.4.0 猫鼬:3.6.0 表达:3.1.0 节点:0.10.1

7 个答案:

答案 0 :(得分:68)

从Mongoose 4.0起,update() can run validatorsfindOneAndUpdate()使用新标记runValidators: true。{/ p>

  

Mongoose 4.0引入了一个在update()findOneAndUpdate()上运行验证器的选项   update()来电。启用此选项将运行验证程序   对于$set来电尝试$unsetvar ClientSchema = new Schema({ name: {type: String, required: true, trim: true} }); var Client = mongoose.model('Client', ClientSchema); 的所有字段。

例如,给定OP的Schema:

var id = req.params.id;
var client = req.body;
Client.update({_id: id}, client, { runValidators: true }, function(err) {
  ....
});

在每次更新时传递标记

你可以使用这样的新标志:

pre

使用pre挂钩

上的标记

如果您不想在每次更新内容时设置标记,可以为findOneAndUpdate()设置// Pre hook for `findOneAndUpdate` ClientSchema.pre('findOneAndUpdate', function(next) { this.options.runValidators = true; next(); }); 挂钩:

update()

然后你可以runValidators使用验证器,而不是每次都传递{{1}}标志。

答案 1 :(得分:54)

你没有做错任何事,validation被实现为Mongoose中的内部中间件,而中间件在update期间没有被执行,因为它基本上是本机驱动程序的传递。 / p>

如果您希望验证客户端更新,则需要find要更新的对象,将新属性值应用于它(请参阅下划线的extend方法),然后调用{{1}在它上面。

Mongoose 4.0更新

正如评论和victorkohl的回答中所述,当您在save中添加$set选项时,Mongoose现在支持验证$unsetrunValidators: true运算符的字段调用

答案 2 :(得分:2)

mongodb默认情况下不对更新运行验证。 为了在默认情况下也使更新时的验证生效,就在连接到mongodb之前,您只能设置全局设置,例如:

mongoose.set('runValidators', true); // here is your global setting

mongoose.connect(config.database, { useNewUrlParser: true });
mongoose.connection.once('open', () => {
    console.log('Connection has been made, start making fireworks...');
}).on('error', function (error) {
    console.log('Connection error:', error);
});

,任何内置或自定义验证也将在更新时运行

答案 3 :(得分:0)

在你的模特中,例如Category.js文件:

const CategorySchema = mongoose.Schema({
category_name : {
type : String,
required : [true, 'Category Name Is Required !'],
trim : true,
maxlength : [30, 'Category Name Is To Long !'],
unique : true,
});
const Category = module.exports = mongoose.model("Category",CategorySchema);

在你的路线档案中:

router.put("/",(req,res,next)=>{
  Category.findOneAndUpdate(
  {_id : req.body.categoryId},
  {$set : {category_name : req.body.category_name} },
  **{runValidators: true}**, function(err,result) {
    if(err){
      if(err.code === 11000){
       var duplicateValue = err.message.match(/".*"/);
       res.status(200).json({"defaultError":duplicateValue[0]+" Is Already Exsist !"});
       }else{
         res.status(200).json({"error":err.message} || {"defaultError":'Error But Not Understood !'});
       }
    }else{
     console.log("From category.js (Route File) = "+result);
     res.status(200).json({"success":"Category Updated Successfully!!"});
    }
});

答案 4 :(得分:0)

exports.updateGroup = (request, response, next) => {
    const requestObj = request.body;
    var conditions = {
        _id: request.body._id,
        communityId: request.body.communityId
    };
    var newValues = {
        $set: requestObj
    };
    Group.updateOne(conditions, newValues, { ***runValidators: true*** }, (err, group) => {
        if (err) return response.json({
            message: "Updation of group failed",
            error: err,
            status: 500
        });
        response.json(group);
    });
};

您需要添加{runValidators:true}作为用于进行更新的验证的第三个参数。

答案 5 :(得分:0)

如果您在猫鼬的配置中添加此选项,它将起作用:

mongoose.set('runValidators',true)

答案 6 :(得分:0)

您可以通过设置选项 runValidators: true 在更新时运行验证。

示例 1:


const Kitten = db.model('Kitten', kittenSchema);

const update = { color: 'blue' };
const opts = { runValidators: true };
Kitten.updateOne({}, update, opts, function() {
  // code
});

示例 2:

const Kitten = db.model('Kitten', kittenSchema);

const update = { color: 'blue' };
const opts = { runValidators: true };
Kitten.updateOne(
  {
    _id: req.params.id
  },
  {
    $set: { ...update },
  },
  opts
).then(result => {
    // code
})

阅读更多:https://mongoosejs.com/docs/validation.html#update-validators