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

Posted

技术标签:

【中文标题】通过 Model.save() 更新时触发 Mongoose 预保存挂钩【英文标题】:Mongoose pre save hook is triggering while updating via Model.save() 【发布时间】:2020-05-13 18:50:37 【问题描述】:

我正在通过 pre hook 为 mongodb 文档保存一个较小的唯一 ID。

schema.pre('save', function(next) 
    this.refId = uid();
    next();
);

据我了解,save 挂钩仅在创建文档时运行。

但是当我通过查询获取文档并尝试通过添加一些新数据来保存它时,唯一 id (refId) 字段也会更新。

const foo = Foo.findOne(refId: 'fwe23fw23');

Foo.field = 'new value';
Foo.save(); // runs pre hook again;

这让我相信 save 钩子在每个 save() 查询上运行,无论它是否是 createupdate 方法。

如何确保refId 只创建一次,并且在任何更新操作中都不会更改?

注意:我知道我可以在模型本身上使用updateOne() 来更新文档。但我想了解为什么保存文档本身不起作用。

【问题讨论】:

【参考方案1】:

document.save()Model.create 都会触发预保存挂钩。

您可以使用isNew 属性来检查文档是否已创建。

schema.pre("save", function(next) 
  if (this.isNew) 
    this.refId = uid();
  

  next();
);

现在 refId 只会在创建文档时创建一次,使用保存时它的值不会改变。

【讨论】:

以上是关于通过 Model.save() 更新时触发 Mongoose 预保存挂钩的主要内容,如果未能解决你的问题,请参考以下文章

model.save没有更新模型值

在 model.save 或 model.save 中捕获数据库异常!方法?

如何修改触发器以更新 PostgreSQL 中的单个属性

在 model.save() 中处理竞争条件

我可以让 model.save() 有一个返回值吗?

Cakephp 的 beforeSave() 不使用 $model::save() 保留新数据