首页 > 解决方案 > Mongoose deleteMany子文档和相关子文档

问题描述

我有一个文档项目,其中包含一组子文档,以及架构任务。Tasks 有一组带有模式 Comments 的子文档。

const projectSchema = new Schema({
  _id: Schema.Types.ObjectId,
  name: { type: String, required: true, unique: true },
  description: { type: String, default: '' },
  tasks: [{ type: Schema.Types.ObjectId, ref: 'Threads' }]
});
module.exports = mongoose.model('Project', projectSchema);

const tasksSchema = new Schema({
  projectId: { type: Schema.Types.ObjectId },
  _id: Schema.Types.ObjectId,
  title: { type: String, required: true },
  text: { type: String, required: true },
  comments: [{ type: Schema.Types.ObjectId, ref: 'Replies' }]
})
module.exports = mongoose.model('Tasks', tasksSchema);

const commentSchema = new Schema({
  taskId: { type: Schema.Types.ObjectId },
  _id: Schema.Types.ObjectId,
  text: { type: String, required: true }
})
module.exports = mongoose.model('Comment', commentSchema);

当我删除项目文档时,我想删除与该项目相关的每个任务和每个评论。要删除项目,我使用 findOneAndDelete 所以我设置了一个后中间件来删除所有任务

projectSchema.post('findOneAndDelete', function(doc, next) {
  mongoose.model('Tasks').deleteMany({ projectId: doc._id }).exec(); 
  next();
})

但是现在我不知道如何删除每条评论,因为 deletemany 返回一个带有操作结果的对象。我应该映射任务数组并每次调用 findOneAndDelete 然后删除每条评论吗?对于很多任务来说,它看起来效率很低。

标签: javascriptmongodbexpressmongoose

解决方案


在帖子中嵌入评论怎么样?因为它是一对多(不是很大)的关系。因此,在您删除项目的代码中,您首先删除包含所有评论的所有帖子,只有在成功后您才能删除该项目。它还将显着提高您的阅读性能,因为您只需返回单个帖子文档而不是多个(1post + 许多评论)文档。

也可以将帖子嵌入到项目中,但根据可能帖子的大小和数量,最好将其保留为单独的文档。在这种情况下,您需要一些逻辑来确保一致性。在这里您可以使用 mongodb 的新功能事务。但我认为在这种情况下不需要事务。(而且我现在发现它很不稳定)你可以使用“最终一致性”方法。

基本上,您只需删除与项目相关的所有帖子,然后删除一个项目。然后你运行批处理来检查是否有任何不一致。(检查是否有任何项目不存在的帖子。如果不存在则删除帖子)


推荐阅读