猫鼬:使用钩子/中间件删除引用的对象(有很多)

时间:2018-08-28 17:57:08

标签: javascript node.js mongodb mongoose mongoose-schema

在使用Mongoose的nodejs应用程序中,我有一个有很多关系:应用程序有很多AppClient。

型号:

const mongoose = require('mongoose')

const appSchema = new mongoose.Schema({
  name: String,
  appClients : [{ type: mongoose.Schema.Types.ObjectId, ref: 'AppClient' }]
})

const App = mongoose.model('App', appSchema)

module.exports = App

const appClientSchema = new mongoose.Schema({
  access_key: String,
  secret_key: String
})

const AppClient = mongoose.model('AppClient', appClientSchema)

问题是,我想删除与某个App文档相关的所有AppClients文档。 我当前的代码是:

exports.delete = async function(req, res, next) {

  const app = await App.findOne({ _id: req.params['id']}).exec()
  const listToDelete = [...app.appClients]

  await App.deleteOne({ _id: req.params['id']}).exec()
  await AppClient.remove({_id: {$in: listToDelete}}).exec()

  res.redirect('/apps')
}

这有效,但是我想知道如何使用钩子。我看过middleware,但是我无法使其与pre('remove')一起使用,因此从未调用过它。我在用这样的东西:

appSchema.pre('remove', (next) => {
  console.log('pre remove') //never called
})

2 个答案:

答案 0 :(得分:1)

remove是在架构级别(例如您的示例)中指定的middleware,但它在文档级别运行。因此,执行此操作的唯一方法是获取文档,然后在文档上执行remove()

const app = await App.findOne({ _id: req.params['id']}).exec();
await app.remove(); //prints 'pre remove'

猫鼬文档中有一个关于此的段落:

  

注意:没有针对remove()的查询挂钩,仅针对文档。如果设置了“删除”挂钩,则在调用myDoc.remove()时将触发该钩子,而不是在调用MyModel.remove()时将其触发。注意:create()函数会触发save()钩子。

答案 1 :(得分:0)

根据the documentation,您应该能够在没有第一手发现文档的情况下使用该挂钩。

appSchema.pre('remove', { query: true }, function() {
  console.log('remove');
});