处理带有关系字段的文档的删除

时间:2019-04-09 14:23:33

标签: mongodb mongoose

我有3个收藏集,用户,帖子和评论。

用户架构

{
  posts: [{ type: Schema.Types.ObjectId, ref: 'Post' }],
  likes: {
    comments: [{ type: Schema.Types.ObjectId, ref: 'Comment' }],
    posts: [{ type: Schema.Types.ObjectId, ref: 'Post' }],
  }
}

发布架构

{
  author: { type: Schema.Types.ObjectId, ref: 'User' },
  likes: [{ type: Schema.Types.ObjectId, ref: 'User' }],
  comments: [{ type: Schema.Types.ObjectId, ref: 'Comment' }],
}

评论模式

{
  author: { type: Schema.Types.ObjectId, ref: 'User' },
  post: { type: Schema.Types.ObjectId, ref: 'Post', },
}

现在这是我要删除帖子以及与之相关的所有步骤的步骤,例如从作者文档帖子字段中删除帖子ID,用户喜欢帖子,评论,用户喜欢评论。

这是我使用的函数,它可以正常工作,并且一切都很好,但是我想知道是否有更好的方法来处理此问题?

PostSchema.statics.deletePost = async function (postId) {
  const post = await this.findById(postId);
  const commentIds = post.comments;

  await Promise.all([
    User.findByIdAndUpdate(
      post.author,
      { $pull: { posts: postId } },
    ),
    User.updateMany(
      { _id: { $in: post.likes } },
      { $pull: { 'likes.posts': postId } },
    ),
    commentIds.map(async (commentId) => {
      const comment = await Comment.findById(commentId);

      User.findByIdAndUpdate(
        comment.author._id,
        { $pull: { comments: commentId } },
      );

      User.updateMany(
        { _id: { $in: comment.likes } },
        { $pull: { 'likes.comments': commentId } },
      );
    }),
    this.findByIdAndDelete(postId),
  ]);

  return post._id;
};

1 个答案:

答案 0 :(得分:0)

您的代码可能会导致数据库不一致。

在处理多个文档时,请使用MongoDB 4中的MULTI-DOCUMENT TRANSACTIONS新功能。这意味着所有文档/集合都将被更新,或者如果出现问题则不更新。整个交易将是原子的。

OR

高效地设计架构,其中包括您所有3种不同的架构。因为对单个文档的操作是原子的。 在这里阅读 https://docs.mongodb.com/manual/core/transactions/