在 pre updateOne 钩子中设置 document: true, query: false,不会触发钩子

Posted

技术标签:

【中文标题】在 pre updateOne 钩子中设置 document: true, query: false,不会触发钩子【英文标题】:Setting document: true, query: false in pre updateOne hook, does not trigger the hook在 pre updateOne 钩子中设置 document: true, query: false,不会触发钩子 【发布时间】:2021-09-13 08:26:01 【问题描述】:

我正在尝试让 schema.pre("updateOne"...) 挂钩与 Mongoose 一起使用,但我不知道我做错了什么。

我有一个Department 的简单架构,它有一个nameinitials

如果名称被更新,我也想更新首字母,所以我需要函数中的文档和查询,我需要查询以便我可以创建新的首字母,并检查它们是否已经存在,然后才允许更新,例如:

schema.pre("updateOne", function(next) 
  const query = ???;
  const document = ???;

  document.initials = query.name.substring(0, 4).toUpperCase();

  next();
);

我曾尝试使用 document: true, query: false ,但这只是完全跳过了钩子,其中的代码根本不会被执行,而且我仍然无法访问这两个。

我正在努力寻找任何有意义的资源,其中包含有关使用 pre/post updateOne 钩子的示例。

我发起 updateOne 的方式:

await DepartmentModel.updateOne(
   _id: Types.ObjectId(id) ,
  
    ...departmentUpdateInfo,
  
);

【问题讨论】:

【参考方案1】:

https://mongoosejs.com/docs/middleware.html#notes 非常清楚“updateOne”不适用于模型:

这是因为 pre('updateOne') 文档中间件挂钩到 Document#updateOne() 而不是 Query#updateOne()。

schema.pre('updateOne',  document: true, query: false , function() 
  console.log('Updating');
);
const Model = mongoose.model('Test', schema);

const doc = new Model();
await doc.updateOne( $set:  name: 'test'  ); // Prints "Updating"

// Doesn't print "Updating", because `Query#updateOne()` doesn't fire
// document middleware.
await Model.updateOne(,  $set:  name: 'test'  );

我怀疑我能比在文档中更好地解释它,但是当您调用 DepartmentModel.updateOne 时,它会直接转换为 db.departments.updateOne() mongodb 查询。 javascript中没有Depratment文档。

为了让你的钩子工作,你需要先加载文档,例如

let department = await DepartmentModel.findOne(
   _id: Types.ObjectId(id) 
);

然后在 document 级别调用 updateOne:

await department.updateOne(
  
    ...departmentUpdateInfo,
  
);

【讨论】:

谢谢,现在可以了,我是新手,pre updateOne 的预期用途是什么?向它添加更多数据还是?找到发送它的文档(就像我在 atm 做的那样)并在那里更新它,获取查询并处理查询,它仍然更新同一个文档有什么区别?你能指出一些可以解释这一点的资源吗?我看不到这两种方法的用例 模型级别的UpdateOne 效率更高,因为您不需要查询文档并将其加载到nodejs 内存中。 mongoosejs.com/docs 和 github.com/Automattic/mongoose 是最好的信息来源。我必须承认它的结构不是很好,所以我们正试图填补 *** 上的空白。如果答案解决了问题,请考虑采纳。

以上是关于在 pre updateOne 钩子中设置 document: true, query: false,不会触发钩子的主要内容,如果未能解决你的问题,请参考以下文章

mongoose更新前修改数据库

如何在钩子中设置值

在两个线程中设置两个鼠标钩子

无法使用钩子在 React 中设置状态

反应:无法使用 useContext 钩子在 app.js 中设置上下文状态

在WPF中设置快捷键,比如ctrl+Enter,shif+D。可否借参考下MyHotKeyClass