如何在 Mongoose 中使用预保存挂钩数据库值?

Sta*_*uan 1 mongoose mongodb node.js

我想在预保存挂钩之前获取对象的值,并将其与新值进行比较。正如在mongoose get db value in pre-save hook和https://github.com/Automattic/mongoose/issues/2952 中所建议的,我做了一个 post-init 钩子,将它复制到 doc._original。问题是我不确定如何在不同的钩子中访问这个 ._original 。

FieldSchema
  .post('save', function (doc) {
    console.log(doc._original);
  });

FieldSchema
  .post('init', function (doc) {
    doc._original = doc.toObject();
  });
Run Code Online (Sandbox Code Playgroud)

我知道 post save 钩子中的文档与 post init 钩子中的文档不同,但我如何访问原始文档?

lag*_*lex 5

您只能访问在其架构中定义的数据库上的属性。因此,由于您可能尚未_original在架构中定义为属性,因此您无法访问,甚至无法设置它。

一种方法是_original在您的架构中明确定义。

但要获得和设置属性不会在你的架构中定义:使用.get,并.set与{strict:false}

FieldSchema
  .post('save', function (doc) {
    console.log(doc.get('_original'));
  });

FieldSchema
  .post('init', function (doc) {
    doc.set('_original', doc.toObject(), {strict: false});
  });
Run Code Online (Sandbox Code Playgroud)

请注意{strict: false}传递给.setwhich的选项是必需的,因为您正在设置架构中未定义的属性。


更新:

我之前没有注意到的第一件事是,在您的问题标题中,您需要预保存钩子,但在您的代码中,您实际上有一个保存后钩子(这是我回答的基础)。我希望你知道你在做什么,在保存文档后调用 post save 钩子。

但在我看来,从我可以理解的问题中你的原始意图是什么,我认为你实际上应该使用预保存钩子和它的异步版本(通过next回调),这样你就可以.find(检索)数据库中的文档,这将是原始版本,因为新版本尚未保存(预保存),因此您无需实际保存任何新字段即可进行比较,这似乎是一种反模式。

所以像:

FieldSchema
  .pre('save', function (next) {
    var new_doc = this;
    this.constructor   // ? mongoose.model('…', FieldSchema).findById
      .findById(this.id, function(err, original){
        console.log(original);
        console.log(new_doc);
        next();
      });
  });
Run Code Online (Sandbox Code Playgroud)

http://mongoosejs.com/docs/middleware.html