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

MongoDB聚合查询:用$lookup关联集合并分组统计投票数

Mongoose聚合查询实现选项票数统计及占比计算

针对你的需求,这里提供完整的Mongoose聚合查询方案,实现每个投票选项的票数统计、占比计算,同时保留票数为0的选项:

Option.aggregate([
  // 关联votes集合,获取对应选项的所有投票记录
  {
    $lookup: {
      from: "votes",
      localField: "_id",
      foreignField: "option",
      as: "voteDocs"
    }
  },
  // 计算当前选项的总票数
  {
    $addFields: {
      totalVotes: { $size: "$voteDocs" }
    }
  },
  // 聚合所有选项数据,统计总投票数
  {
    $group: {
      _id: null,
      options: { $push: "$$ROOT" },
      totalAllVotes: { $sum: "$totalVotes" }
    }
  },
  // 展开选项数组,回到单文档结构
  {
    $unwind: "$options"
  },
  // 计算投票占比,处理总票数为0的边界情况
  {
    $addFields: {
      votePercentage: {
        $cond: {
          if: { $eq: ["$totalAllVotes", 0] },
          then: "0",
          else: {
            $toString: {
              $round: { $multiply: [{ $divide: ["$options.totalVotes", "$totalAllVotes"] }, 100] }
            }
          }
        }
      }
    }
  },
  // 整理输出字段,匹配目标格式
  {
    $replaceWith: {
      _id: "$options._id",
      name: "$options.name",
      totalVotes: "$options.totalVotes",
      votePercentage: "$votePercentage"
    }
  },
  // 按票数降序排序,和示例结果顺序一致
  {
    $sort: { totalVotes: -1 }
  }
])
.then(result => console.log(result))
.catch(err => console.error(err));

各阶段说明:

  1. $lookup:通过options._id与votes.option关联,把匹配到的投票文档存入voteDocs数组。
  2. $addFields:用$size获取voteDocs的长度,得到当前选项的totalVotes。
  3. $group:将所有数据聚合为一个分组,保存所有选项数据到options数组,同时计算全局总票数totalAllVotes。
  4. $unwind:拆分options数组,让每个选项回到独立文档结构,方便后续计算占比。
  5. $addFields:计算单选项票数占总票数的比例,乘以100后取整并转为字符串;如果总票数为0,直接返回"0"避免除以0错误。
  6. $replaceWith:仅保留目标字段,调整文档结构与需求一致。
  7. $sort:按totalVotes降序排列,匹配示例结果的顺序。

注意事项:

  • 确保$lookup中的from参数与你的votes集合名称一致(Mongoose默认会将模型名转为小写复数作为集合名)。
  • 示例中的百分比数值(35、25)可能是笔误,按真实票数计算的话,总票数5,A的3票占60%,C的2票占40%,如果需要自定义百分比逻辑,可以调整$multiply或$round的参数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 16:57:35