mongoose:中间件预删除选项不起作用

问题描述 投票:0回答:4

猫鼬的文档说:

Mongoose - 架构预

Schema.prototype.pre():
参数:
«String|RegExp» 方法 匹配方法名称的名称或正则表达式
[选项] «对象»
[options.document] «Boolean» 如果 name 是文档和查询中间件的挂钩,则设置为 true 以在文档中间件上运行。
[options.query] «Boolean» 如果名称是文档和 查询中间件,设置为 true 以在查询中间件上运行。
回调“函数”

还有关于预钩子“deleteOne”:
Mongoose - 中间件

文档中间件支持以下文档功能。在 文档中间件功能,这里指的是文档:
...删除一个

以下模型和查询功能支持查询中间件。在查询中间件>函数中,这指的是查询:
...删除一个

所以,deleteOne 位于 Document 和 Query hook 中,现在让我们尝试使用它:

mySchema.pre('deleteOne', { document: true }, function(next) {
  console.log(this)
  next()
})

Result:这里指的是Query,而不是Document。为什么?

node.js mongodb mongoose
4个回答
16
投票

哦,从文档中不清楚,“this”仅指document#deleteOne中的文档。

所以,‘deleteOne’钩子的正确用法是:
型号中:

DocSchema.pre('deleteOne', { document: true }, function(next) {
  console.log(this)
  next()
})

稍后在代码中(在控制器等中):

const doc = await DocModel.findOne({ name: 'myDoc' })
await doc.deleteOne()

现在“this”指的是文档🎉


4
投票

您需要添加到选项:

{ query: false }

如果没有,预挂钩将运行两次:

首先是文档 -

this
将是文档

第二个查询 -

this
将是查询

这样写:

DocSchema.pre('deleteOne', { document: true, query: false }, function (next) {
  console.log(this);
});

1
投票

在钩子内获取“this”运行查询的另一种方法

await ShopModel.deleteOne({ shop: shopDomain });

ShopSchema.pre("deleteOne", async function (next) {
  const shopDoc = await this.model.findOne(this.getQuery());
  await DiscountSettingsModel.findByIdAndRemove(shop.discountSettings);
  next();
});

1
投票

要添加到 Maxim答案中,必须在编译模型之前定义预中间件调用(请参阅预文档)。

所以你将会:

// Create schema
const DocSchema = new Schema(schemaFields)

// Attach middleware
DocSchema.pre('deleteOne', { document: true }, function(next) {
  console.log(this)
  next()
})

// Now create the model.
const DocModel = model('Doc', DocSchema)
© www.soinside.com 2019 - 2024. All rights reserved.