【问题标题】:Handling deletion of documents with relational fields处理删除具有关系字段的文档
【发布时间】:2019-08-30 21:10:43
【问题描述】:

我有 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,用户喜欢帖子,cmets,用户喜欢 cmets。

这是我使用的功能,它可以工作,一切都很好,但我想知道是否有更好的方法来处理这个问题?

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;
};

【问题讨论】:

  • 对于干净的代码,您必须在每个承诺中使用await。有了一系列的承诺,你应该使用Promise.all。否则你的代码没问题。

标签: mongodb mongoose


【解决方案1】:

您的代码可能会在数据库中造成不一致。

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

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

【讨论】:

    猜你喜欢
    • 2021-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-09
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多