猫鼬中间件预更新

时间:2015-07-01 23:51:35

标签: node.js mongoose

我正在使用

schema.pre('save', function (next) {
  if (this.isModified('field')) {
    //do something
  }
});

但我现在需要在isModified挂钩中使用相同的函数schema.pre('update',但它不存在。有谁知道如何在update钩子中使用相同的功能?

7 个答案:

答案 0 :(得分:10)

根据this不可能:

  

查询中间件与文档中间件的区别在于微妙但是   重要的方法:在文档中间件中,这是指文档   正在更新。在查询中间件中,mongoose不一定有   对正在更新的文档的引用,因此这是指查询   对象而不是正在更新的文档。

update是查询中间件,this是指没有isModified方法的查询对象。

答案 1 :(得分:2)

@Jeremy我已经到了同样的问题,最后得到了一个解决方法:

schema.pre('update', function(next) {
        const modifiedField = this.getUpdate().$set.field;
        if (!modifiedField) {
            return next();
        }
        try {
            const newFiedValue = // do whatever...
            this.getUpdate().$set.field = newFieldValue;
            next();
        } catch (error) {
            return next(error);
        }
    });

从这里采取:https://github.com/Automattic/mongoose/issues/4575

使用此功能,您可以检查字段是否有任何更新,但无法检查传入值是否与存储值不同。 它适用于我的用例(重置后加密密码)

我希望它有所帮助。

答案 2 :(得分:0)

Schema.pre('updateOne', function (next) {
    const data = this.getUpdate()

    data.password = 'Teste Middleware'
    this.update({}, data).exec()
    next()
})

  const user = await User.updateOne({ _id: req.params.id }, req.body)

这对我有用

答案 3 :(得分:0)

这不是OP的解决方案,但这对我有用 我尝试过的最佳解决方案,取自here

schema.pre("update", function(next) {
        const password = this.getUpdate().$set.password;
        if (!password) {
            return next();
        }
        try {
            const salt = Bcrypt.genSaltSync();
            const hash = Bcrypt.hashSync(password, salt);
            this.getUpdate().$set.password = hash;
            next();
        } catch (error) {
            return next(error);
        }
    });

答案 4 :(得分:0)

但是您可以使用查询挂钩;尽管您可能需要使用POST而不是PRE挂钩。

schema.pre('findOneAndUpdate', async function() {
  const docToUpdate = await this.model.findOne(this.getQuery());
  console.log(docToUpdate); // The document that `findOneAndUpdate()` will modify
});

所以

schema.post(/update/i, async (query, next) {
  if (query instanceof mongoose.Query) {
    await Model.find(query.getQuery()).each((el) => {
      if (isModified('field')) {
        //do something
      }
    })
  }
  next()
});

答案 5 :(得分:0)

好吧,在更新方法中密码哈希的情况下,我所做的是:

{{1}}

别忘了导入所需的npm模块。

答案 6 :(得分:0)

实际上 André Rodrigues 答案几乎是完美的,但在 Mongoose v5.13.0 你可以很容易地改变 body 本身而无需执行它

schema.pre('updateOne', async function () {
  let data = this.getUpdate();
  const salt = await bcrypt.genSalt();
  data.password = await bcrypt.hash(data.password, salt);
});

一如既往地欢迎:)