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

时间:2015-06-14 07:46:08

标签: node.js mongodb mongoose

我想在预保存挂钩之前获取对象的值,并将其与新值进行比较。正如mongoose get db value in pre-save hookhttps://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();
  });

我知道post保存挂钩中的doc与post init挂钩中的doc不同,但是如何访问原始文件?

1 个答案:

答案 0 :(得分:3)

您只能访问已在其架构中定义的数据库的属性。因此,您可能尚未将_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});
  });

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

更新

我之前没有注意到的第一件事就是在你的问题标题中你想要预先 -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();
      });
  });

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