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

Posted

技术标签:

【中文标题】如何在 Mongoose 中使用预保存挂钩数据库值?【英文标题】:How do I use a pre save hook database value in Mongoose? 【发布时间】:2015-08-29 21:07:19 【问题描述】:

我想在 pre-save 钩子之前获取对象的值并将其与新值进行比较。正如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();
  );

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

【问题讨论】:

【参考方案1】:

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

一种方法显然是在您的架构中定义_original

但要获取和设置在您的架构中定义的属性:使用.get.setstrict:false

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

FieldSchema
  .post('init', function (doc) 
    doc.set('_original', doc.toObject(), strict: false);
  );

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


更新:

我之前没有注意到的第一件事是,在你的问题标题中你想要 pre-save 钩子,但在你的代码中你实际上有一个 post-save 钩子(这是我的答案在)。我希望你知道你在做什么,在保存文档之后 调用 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();
      );
  );

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

【讨论】:

一种方式优于另一种方式吗?这也是获得预存价值的最佳方式,还是有其他更好的方式? @StanleyYuan 抱歉,我之前没有注意到这个问题。请在我的答案中查看更新。希望对您有所帮助。

以上是关于如何在 Mongoose 中使用预保存挂钩数据库值?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Node.js / Express 应用程序的 Mongoose 预挂钩中查询?

通过 Model.save() 更新时触发 Mongoose 预保存挂钩

测试猫鼬预保存钩子

在 Mongoose 保存后挂钩中捕获并忽略/抑制错误

猫鼬密码哈希

Nest.js/Mongoose:为啥我的预保存钩子无法触发?