【问题标题】:how to let updatemany validate mongoose schema on every modified document ?如何让 updatemany 在每个修改过的文档上验证猫鼬模式?
【发布时间】:2017-09-09 08:00:29
【问题描述】:

在尝试验证在 Model::updateMany(或 update + mutli:true)请求中修改的文档的架构时,我遇到了 mongoose 架构验证的问题。 我有以下架构:

  var BusinessesSchema = new Schema({
    label: {
      type: String,
      required: true
    },
    openingDate: {
      type: Date,
      required: true
    },
    endingDate: {
      type: Date,
      validate: function(value) {
        if (this.constructor.name === 'Query') {
          // Looks like this is a validation for update request
          var doc = null;
          switch (this.op) {
            case 'update':
            case 'updateMany': {
              doc = this._update.$set;
              break;
            }
            case 'findOneAndUpdate': {
              doc = this._update;
              break;
            }
            default:
            // keep null, will throw an error
          }
          return doc.openingDate < value;
        }
        else {
          return this.openingDate < value;
        }
      }
    }
  });

我想在endingDate::validate 函数中访问修改后的文档值(“this”),以确保每个修改后的文档的结束日期大于开始日期。

即使在使用 pre-hook(用于 update 和 updateMany,如下所示)时,我仍然找不到任何方法来访问修改后的文档值以在设置 multi 时(或调用 updateMany 时)执行我的检查。

BusinessesSchema.pre('update', function(next) {
  this.options.runValidators = true;
  this.options.context = 'query';
  next();
});

BusinessesSchema.pre('updateMany', function(next) {
  this.options.runValidators = true;
  this.options.context = 'query';
  next();
});

我可能错过了一些东西,非常感谢这里的帮助。

【问题讨论】:

    标签: node.js validation mongoose schema this


    【解决方案1】:

    不能这样做。使用updateMany 可以做的最好的事情是从this 捕获查询上下文,并分析更新。像这样的:

    Schema.pre('updateMany', function (next) {
        const update = this.getUpdate();
        if (update.$set && update.$set && !validateUpdate(update.$set)) {
            throw new Error('Invalid Update');
        }
        next();
    });
    

    如果您想在更新之前使用save 挂钩对生成的文档进行验证,您可以使用游标:

    Schema.pre('save', function(next) {
        if (!validDoc(this)) {
            throw new Error('Invalid Doc');
        }
        next();
    }
    Schema.statics.updateManyWithValidation = async function(criteria, update) {
            const cursor = Model.find(criteria).cursor();
            let doc = null;
            do {
                doc = await cursor.next();
                Object.assign(doc, update);
                await doc.save();
             } while(doc != null);
        }
    

    现在,请记住,这是一项成本更高的操作,因为您要获取文档、应用更改,然后单独保存它们。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-16
      • 2021-06-20
      • 2018-09-08
      • 2011-11-14
      • 2019-11-06
      • 2020-12-25
      相关资源
      最近更新 更多