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

如何用单条MongoDB查询返回热门与流行两类排名书籍列表

单MongoDB聚合查询生成双排名列表方案

你可以利用MongoDB的$facet聚合阶段实现单查询生成两个独立排名列表,同时计算两种评分。以下是具体实现方案:

核心思路

  1. 先计算全局统计数据(用于贝叶斯平均计算)
  2. 为每本书计算两种评分:贝叶斯平均(流行排名) 和自定义热门评分
  3. 通过$facet并行执行两个排序逻辑,分别生成流行和热门书籍列表

完整聚合查询代码

db.books.aggregate([
  // 1. 统计全局评分总和、总投票数,同时保留所有书籍数据
  {
    $group: {
      _id: null,
      totalRatingSum: { $sum: { $multiply: ["$rating", "$ratingCount"] } },
      totalVoteCount: { $sum: "$ratingCount" },
      bookList: { $push: "$$ROOT" }
    }
  },
  // 2. 计算全局平均评分,设定最小投票阈值,展开书籍列表
  {
    $project: {
      globalAvgRating: { $divide: ["$totalRatingSum", "$totalVoteCount"] },
      minRequiredVotes: { $literal: 100 }, // 可根据业务调整阈值
      bookList: 1
    }
  },
  { $unwind: "$bookList" },
  // 3. 计算两种评分:贝叶斯平均(流行)、自定义热门评分
  {
    $project: {
      bookInfo: "$bookList",
      bayesianAvg: {
        $let: {
          vars: {
            voteCount: "$bookList.ratingCount",
            bookRating: "$bookList.rating",
            minVotes: "$minRequiredVotes",
            globalAvg: "$globalAvgRating"
          },
          in: {
            $add: [
              { $multiply: [{ $divide: ["$$voteCount", { $add: ["$$voteCount", "$$minVotes"] }] }, "$$bookRating"] },
              { $multiply: [{ $divide: ["$$minVotes", { $add: ["$$voteCount", "$$minVotes"] }] }, "$$globalAvg"] }
            ]
          }
        }
      },
      hotScore: {
        $multiply: ["$bookList.ratingCount", "$bookList.rating"] // 替换为你的热门算法
      }
    }
  },
  // 4. 用$facet生成两个独立排名列表
  {
    $facet: {
      popularBooks: [
        { $sort: { bayesianAvg: -1 } },
        { $limit: 20 }, // 返回前20本,可调整数量
        { $project: {
            title: "$bookInfo.title",
            author_name: "$bookInfo.author_name",
            pub_date: "$bookInfo.pub_date",
            rating: "$bookInfo.rating",
            ratingCount: "$bookInfo.ratingCount",
            bayesianAvg: 1,
            _id: 0
          }
        }
      ],
      hotBooks: [
        { $sort: { hotScore: -1 } },
        { $limit: 20 },
        { $project: {
            title: "$bookInfo.title",
            author_name: "$bookInfo.author_name",
            pub_date: "$bookInfo.pub_date",
            rating: "$bookInfo.rating",
            ratingCount: "$bookInfo.ratingCount",
            hotScore: 1,
            _id: 0
          }
        }
      ]
    }
  }
])

关键细节说明

  • 贝叶斯平均计算:采用行业通用公式,平衡单本书评分和全局平均评分,避免冷门高分书霸榜。minRequiredVotes可根据业务调整(新书多就设小,要过滤冷门就设大)。
  • 热门评分算法:示例用ratingCount * rating作为加权值,你可以替换为实际需求(比如结合发布时间的加权:$add: [{ $multiply: ["$bookList.ratingCount", 0.8] }, { $multiply: [{ $subtract: [new Date(), "$bookList.pub_date"] }, 0.2] }])。
  • $facet阶段:这是实现双列表的核心,它允许在一个聚合中并行执行多个子管道,分别处理两种排序逻辑,最终返回两个独立数组。

返回结果结构

查询会直接返回包含两个列表的文档,可直接返回给前端:

{
  "popularBooks": [
    {
      "title": "XXX",
      "author_name": "XXX",
      "pub_date": ISODate("XXXX-XX-XXTXX:XX:XXZ"),
      "rating": 4.8,
      "ratingCount": 1200,
      "bayesianAvg": 4.72
    },
    // ... 其他书籍
  ],
  "hotBooks": [
    {
      "title": "XXX",
      "author_name": "XXX",
      "pub_date": ISODate("XXXX-XX-XXTXX:XX:XXZ"),
      "rating": 4.5,
      "ratingCount": 5000,
      "hotScore": 22500
    },
    // ... 其他书籍
  ]
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 15:18:14