Nodejs mongoose删除model时,pre和post middleware为什么不会触发

Nodejs mongoose删除model时,pre和post middleware为什么不会触发

blogSchema.pre(‘remove’, function(next){ console.log(‘before remove blog’); console.log(this.id); console.log(this.comments); next(); }); blogSchema.post(‘remove’, function (doc) { console.log(‘remove blog’); console.log(’%s has been removed’, doc._id); });

Blog.findByIdAndRemove(id, function(error, blog){ DBUtil.handleQueryResult(error, blog, options); });


6 回复

Nodejs Mongoose 删除 Model 时 prepost 中间件为什么不会触发?

在使用 Mongoose 处理数据模型操作时,你可能会遇到这样的问题:当你尝试在删除文档时使用 prepost 中间件,但发现它们没有被触发。这可能是由于一些常见的误解或错误配置导致的。

示例代码

假设我们有一个 blogSchema,并且我们已经定义了 prepost 中间件来处理删除操作:

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

// 定义博客文章的模式
const blogSchema = new Schema({
    title: String,
    content: String,
    comments: [{ type: Schema.Types.ObjectId, ref: 'Comment' }]
});

// 定义删除前中间件
blogSchema.pre('remove', function(next) {
    console.log('Before removing blog post');
    console.log(`Blog ID: ${this._id}`);
    console.log(`Comments: ${this.comments.length}`);
    next(); // 确保继续执行删除操作
});

// 定义删除后中间件
blogSchema.post('remove', function(doc) {
    console.log('Blog post removed');
    console.log(`${doc._id} has been removed`);
});

// 创建模型
const Blog = mongoose.model('Blog', blogSchema);

// 删除博客文章
async function deleteBlogPost(blogId) {
    try {
        await Blog.findByIdAndDelete(blogId);
        console.log('Blog post deleted successfully');
    } catch (error) {
        console.error('Error deleting blog post:', error);
    }
}

// 使用示例
deleteBlogPost('1234567890abcdef12345678');

解释

  1. 中间件定义:

    • pre('remove'): 这是一个预删除中间件,在实际删除操作之前执行。
    • post('remove'): 这是一个后删除中间件,在删除操作之后执行。
  2. 删除操作:

    • 使用 findByIdAndDelete() 方法删除文档。注意,这里使用的是 findByIdAndDelete() 而不是 findByIdAndRemove()。尽管 findByIdAndRemove() 仍然可用,但推荐使用 findByIdAndDelete(),因为它更清晰地表明你的意图是删除文档。
  3. 确保中间件触发:

    • pre('remove') 中间件中,确保调用 next() 函数以允许删除操作继续进行。如果不调用 next(),中间件将停止执行,并且删除操作也不会继续。

如果你发现中间件没有被触发,检查以下几点:

  • 确保你正在使用正确的删除方法(如 findByIdAndDelete())。
  • 确保中间件函数中调用了 next()
  • 确保你的数据库连接正确且模型已注册。

通过这些步骤,你应该能够正确地触发 prepost 中间件。


这个我也遇到了 不太清楚啊 求高手解答

楼上正解~

2楼正解~

在使用 Mongoose 的 prepost 中间件时,确保这些中间件能够正确触发,需要遵循一些最佳实践。在你的例子中,pre('remove')post('remove') 中间件没有触发的原因可能是因为 findByIdAndRemove 方法并没有直接调用 remove 方法。

为了确保中间件能够被触发,可以使用 findOneAndDeletedeleteOne 方法来代替 findByIdAndRemove。下面是具体的修改示例:

示例代码

const mongoose = require('mongoose');
const DBUtil = require('./dbUtil'); // 假设这是一个处理数据库查询结果的工具

// 定义 Blog 模型和 schema
const blogSchema = new mongoose.Schema({
  title: String,
  comments: [String]
});

// 定义 pre 和 post 中间件
blogSchema.pre('remove', function(next) {
  console.log('before remove blog');
  console.log(this.id);
  console.log(this.comments);
  next();
});

blogSchema.post('remove', function(doc) {
  console.log('remove blog');
  console.log('%s has been removed', doc._id);
});

const Blog = mongoose.model('Blog', blogSchema);

// 使用 findOneAndDelete 代替 findByIdAndRemove
Blog.findOneAndDelete({ _id: id }, function(error, blog) {
  DBUtil.handleQueryResult(error, blog, options);
});

解释

  1. 中间件定义:你已经在 blogSchema 上定义了 pre('remove')post('remove') 中间件。
  2. 查询方法:使用 findOneAndDelete 方法来替代 findByIdAndRemove。因为 findByIdAndRemove 并不直接触发 remove 钩子,而 findOneAndDelete 会触发 remove 钩子。

通过以上修改,pre('remove')post('remove') 中间件应该能够正常触发。如果你仍然遇到问题,请检查 Mongoose 版本是否兼容,并确保 Mongoose 在项目中的配置是正确的。

回到顶部