You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于MongoDB的类Facebook社交应用帖子多规则排序查询问询

MongoDB类Facebook应用帖子流排序实现方案

以下是基于你提供的Schema实现指定排序规则的聚合查询方案,注意:你的Schema中post和reaction集合缺少createdAt(创建时间)字段,这是实现近6个月反应差值和帖子创建时间排序的必要字段,需要先给这两个集合添加该字段。

核心思路

通过聚合管道的$lookup关联相关集合,计算出每个排序规则对应的数值字段,最后按优先级降序排序。

完整聚合查询(需替换currentUserId为实际当前用户ID)

db.post.aggregate([
  // 1. 关联帖子作者的用户信息,获取作者的location_id
  {
    $lookup: {
      from: "user",
      localField: "author",
      foreignField: "_id",
      as: "authorInfo"
    }
  },
  { $unwind: "$authorInfo" }, // 展开作者信息数组

  // 2. 判断当前用户是否关注该作者
  {
    $lookup: {
      from: "follow",
      let: { authorId: "$author" },
      pipeline: [
        {
          $match: {
            $expr: {
              $and: [
                { $eq: ["$follower", ObjectId("currentUserId")] },
                { $eq: ["$following", "$$authorId"] }
              ]
            }
          }
        }
      ],
      as: "isFollowed"
    }
  },
  {
    $addFields: {
      isFollowed: { $cond: [{ $gt: [{ $size: "$isFollowed" }, 0] }, 1, 0] }
    }
  },

  // 3. 统计帖子的评论数
  {
    $lookup: {
      from: "comment",
      localField: "_id",
      foreignField: "post",
      as: "comments"
    }
  },
  {
    $addFields: {
      commentCount: { $size: "$comments" }
    }
  },

  // 4. 统计反应相关数据
  {
    $lookup: {
      from: "reaction",
      localField: "_id",
      foreignField: "post",
      as: "reactions"
    }
  },
  {
    $addFields: {
      // 统计正向反应数(like+love,用于计算热度)
      reactionHotCount: {
        $sum: {
          $map: {
            input: "$reactions",
            as: "r",
            in: { $cond: [{ $in: ["$$r.type", ["like", "love"]] }, 1, 0] }
          }
        }
      },
      // 计算近6个月正向反应减悲伤反应的差值
      recentReactionDiff: {
        $let: {
          vars: {
            recentReactions: {
              $filter: {
                input: "$reactions",
                cond: {
                  $gte: ["$$this.createdAt", new Date(Date.now() - 6 * 30 * 24 * 60 * 60 * 1000)]
                }
              }
            }
          },
          in: {
            $subtract: [
              {
                $sum: {
                  $map: {
                    input: "$$recentReactions",
                    as: "r",
                    in: { $cond: [{ $in: ["$$r.type", ["like", "love"]] }, 1, 0] }
                  }
                }
              },
              {
                $sum: {
                  $map: {
                    input: "$$recentReactions",
                    as: "r",
                    in: { $cond: [{ $eq: ["$$r.type", "sad"] }, 1, 0] }
                  }
                }
              }
            ]
          }
        }
      }
    }
  },

  // 5. 计算帖子总热度:正向反应数+评论数
  {
    $addFields: {
      postHotness: { $add: ["$reactionHotCount", "$commentCount"] }
    }
  },

  // 6. 判断当前用户与作者是否同地区
  {
    $lookup: {
      from: "user",
      pipeline: [
        { $match: { _id: ObjectId("currentUserId") } },
        { $project: { location_id: 1, _id: 0 } }
      ],
      as: "currentUserLocation"
    }
  },
  { $unwind: "$currentUserLocation" },
  {
    $addFields: {
      sameLocation: {
        $cond: [{ $eq: ["$authorInfo.location_id", "$currentUserLocation.location_id"] }, 1, 0]
      }
    }
  },

  // 7. 按规则降序排序
  {
    $sort: {
      isFollowed: -1,
      postHotness: -1,
      sameLocation: -1,
      recentReactionDiff: -1,
      createdAt: -1
    }
  },

  // 可选:保留业务需要的字段,过滤冗余数据
  {
    $project: {
      content: 1,
      author: 1,
      createdAt: 1,
      isFollowed: 1,
      postHotness: 1
    }
  }
])

各规则实现说明

  • 用户是否关注作者:通过$lookup关联follow集合,匹配当前用户为follower、作者为following的记录,用集合长度判断是否存在关注关系,转成1/0数值用于排序。
  • 帖子热度:定义为「正向反应数(like+love)+评论数」,分别通过$size统计评论数,$map+$sum统计正向反应数,相加得到总热度。
  • 同一地区判断:关联当前用户的location_id,与作者的location_id对比,相等则为1,否则为0。
  • 近6个月反应差值:先通过$filter筛选出近6个月的反应记录,再分别统计正向反应和悲伤反应的数量,计算差值。
  • 帖子创建时间:依赖post集合的createdAt字段,直接按该字段降序排序。

注意事项

  1. 必须给post和reaction集合添加createdAt字段,否则无法实现时间相关的排序规则。
  2. 若数据量较大,建议给follow(follower, following)、reaction(post, createdAt)、comment(post)等字段建立复合索引,提升聚合查询性能。
  3. 可根据业务需求调整$project阶段的返回字段,减少数据传输量。

内容的提问来源于stack exchange,提问作者Michael Anachunam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 04:09:29