猫鼬删除许多子文档及相关子文档

时间:2019-12-20 14:23:28

标签: javascript mongodb express mongoose

我有一个文档项目,其中包含一系列子文档以及一个架构任务。 Tasks包含一系列带有架构注释的子文档。

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,然后删除每个注释吗?对于许多任务而言,效率似乎很低。

1 个答案:

答案 0 :(得分:1)

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

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

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