猫鼬中的最小和最大数量验证

Posted

技术标签:

【中文标题】猫鼬中的最小和最大数量验证【英文标题】:Minimum and maximum number validation in mongoose 【发布时间】:2019-04-23 19:57:51 【问题描述】:

我正在使用带有 Angular 6 的 MEAN 堆栈实现一个 Web 应用程序。我想在那里找到并保存“eValue”。最小值为 0,最大值为 1000。为此,我在模式中将最小值设置为 0,最大值设置为 1000。但是当我输入 -1 并单击“保存”按钮时,它会将 -1 保存在 mongo db 中。我想要的是如果我输入小于 0 的值,它不应该在数据库中保存任何内容。这是我的架构。

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var ObjectId = Schema.ObjectId;

// Schema for extruded height panel
var eValueSchema = new mongoose.Schema(
    userName: 
        type: String
    ,
    eValue: 
        type: Number,
        min: 0,


    , 
);

module.exports = mongoose.model('eValue', eValueSchema);

这是我的发帖路线

var eValue= require('../../../models/mongoModels/eValue');

router.post("/save", function (req, res) 
    var mod = new eValue(req.body);
    eValue.findOneAndUpdate(
        
            userName: req.body.userName,
        ,

        req.body,
         upsert: true, new: true ,

        function (err, data) 
            if (err) 
                console.log(err);
                res.send(err);
             else 

                res.send(mod);
            
        
    );
);

【问题讨论】:

您仍然需要提供default。这就是我想你的意思。 “验证”仅意味着它检查您“实际提供”的任何值,而不是那些从未传递过的值。 我想限制小于 0 和大于 1000 的值 是的,我明白这一点,但你似乎不明白我的意思。您希望该值存储为0,即使您的req.body 内容甚至没有该字段的值,对吗?验证不这样做。这就是default 所做的。两者都需要。 如果该字段为空,则不应存储默认值。例如:如果我输入 -1 它不应该保存任何东西。 并且说它不起作用你到底是什么意思? 【参考方案1】:

因为您使用的是findOneAndUpdate(),并且默认情况下它不会运行验证器或默认值。

您需要将选项与newupsert 一起添加到方法中:

 
    upsert: true,
    new: true,
    runValidators: true,
    setDefaultsOnInsert: true
  

演示:

const  Schema  = mongoose = require('mongoose');

const uri = 'mongodb://localhost:27017/test';
const opts =  useNewUrlParser: true ;

// sensible defaults
mongoose.set('debug', true);
mongoose.set('useFindAndModify', false);
mongoose.set('useCreateIndex', true);

// Schema defs

const testSchema = new Schema(
  name: String,
  value:  type: Number, min: 0, max: 1000, default: 0 
);

const Test = mongoose.model('Test', testSchema);

// log helper

const log = data => console.log(JSON.stringify(data, undefined, 2));

(async function() 

  try 

    const conn = await mongoose.connect(uri, opts);

    // Clean models
    await Promise.all(
      Object.entries(conn.models).map(([k,m]) => m.deleteMany())
    )

    // Do something

    // Set validators and defaults
    let result1 = await Test.findOneAndUpdate(
       name: 'Bill' ,
       name: 'Bill' ,
      
        upsert: true,
        new: true,
        runValidators: true,
        setDefaultsOnInsert: true
      
    );
    log(result1);

    // No validator and no default
    let result2 = await Test.findOneAndUpdate(
       name: 'Ted' ,
       name: 'Ted' ,
      
        upsert: true,
        new: true,
      
    );
    log(result2);

    // Expect to fail
    try 
      let result3 = await Test.findOneAndUpdate(
         name: 'Gary' ,
         name: 'Gary', value: -1 ,
        
          upsert: true,
          new: true,
          runValidators: true,
          setDefaultsOnInsert: true
        
      );
      log(result3);
     catch(e) 
      console.error(e)
    

    console.log('Tests done!');


   catch(e) 
    console.error(e)
   finally 
    mongoose.disconnect()
  

)()

这是我们期望为第一个动作起作用的属性,但第二个动作实际上不会插入默认值。请注意,Mongoose 文档结果的“日志”实际上显示了 0,即使您可以看到它没有保存到数据库中。

对于最后一个示例,我们打开验证器并获得预期的验证错误。删除该选项不会引发错误。

样本输出:

Mongoose: tests.deleteMany(, )
Mongoose: tests.findOneAndUpdate( name: 'Bill' ,  '$setOnInsert':  __v: 0, value: 0, _id: ObjectId("5bf52c1b9d265f1507f94056") , '$set':  name: 'Bill'  ,  upsert: true, runValidators: true, setDefaultsOnInsert: true, remove: false, projection: , returnOriginal: false )

  "value": 0,
  "_id": "5bf52c1b9d265f1507f94056",
  "name": "Bill",
  "__v": 0

Mongoose: tests.findOneAndUpdate( name: 'Ted' ,  '$setOnInsert':  __v: 0 , '$set':  name: 'Ted'  ,  upsert: true, remove: false, projection: , returnOriginal: false )

  "value": 0,
  "_id": "5bf52c1b97f623c9da4341a0",
  "name": "Ted",
  "__v": 0

 ValidationError: Validation failed: value: Path `value` (-1) is less than minimum allowed value (0).
    ... rest of stack ...
    at ValidationError.inspect     at formatValue (util.js:561:31)
    at inspect (util.js:371:10)
    at Object.formatWithOptions (util.js:225:12)
    at Console.(anonymous function) (console.js:193:15)
    at Console.warn (console.js:210:31)
    at /home/neillunn/working/minmax/index.js:75:15
    at process._tickCallback (internal/process/next_tick.js:68:7)
  errors:
    value:
       ValidatorError: Path `value` (-1) is less than minimum allowed value (0).
          at new ValidatorError         message: 'Path `value` (-1) is less than minimum allowed value (0).',
        name: 'ValidatorError',
        properties: [Object],
        kind: 'min',
        path: 'value',
        value: -1,
        reason: undefined,
        [Symbol(mongoose:validatorError)]: true  ,
  _message: 'Validation failed',
  name: 'ValidationError' 
Tests done!

【讨论】:

谢谢。解释得很好。

以上是关于猫鼬中的最小和最大数量验证的主要内容,如果未能解决你的问题,请参考以下文章

如何使用猫鼬需要验证在猫鼬中插入多个文档?

如何在猫鼬中转换为字符串?

猫鼬中的 findByIdAndRemove 和 findByIdAndDelete 有啥区别?

猫鼬中的用户、帖子和评论模型

如何在同一组的猫鼬中找到 $count?

猫鼬中的填充方法(节点js)