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

如何在MongoDB中查询条目时统计各选项的投票数?

嘿,我懂你现在的需求——要查询投票条目时,同时返回每个选项的对应投票数对吧?刚接触MongoDB的聚合、lookup这些概念确实需要点时间适应,我一步步给你拆解怎么实现这个需求,完全贴合你给出的数据模型和期望结果。

首先先确认下:看你给出的Votes数据,里面的entryId其实应该是指向选项的_id对吧?(可能是字段名笔误,不过我先按你给的字段来写,后面会提怎么改)

实现思路

核心思路是先统计每个选项的投票数,再把统计结果关联到对应的条目选项上,同时要保证所有原始选项都保留,哪怕是0票的选项。用MongoDB的聚合管道可以分两步完成:

  1. 对Votes集合分组统计每个选项的投票数,再和Entries做关联
  2. 把统计的投票数匹配到每个条目对应的选项中,补全0票的情况

完整聚合查询代码

db.Entries.aggregate([
  // 第一步:关联Votes并获取当前条目下所有选项的投票统计
  {
    $lookup: {
      from: "Votes",
      let: { entryOptions: "$options" },
      pipeline: [
        // 先统计每个选项的总票数
        {
          $group: {
            _id: "$entryId", // 这里如果你的字段是optionId,就改成"$optionId"
            votes: { $sum: 1 }
          }
        },
        // 只保留当前条目包含的选项的统计结果
        {
          $match: {
            $expr: {
              $in: ["$_id", "$$entryOptions._id"]
            }
          }
        }
      ],
      as: "voteCounts"
    }
  },
  // 第二步:将投票数匹配到对应的选项上,补全0票的情况
  {
    $project: {
      options: {
        $map: {
          input: "$options",
          as: "opt",
          in: {
            _id: "$$opt._id",
            name: "$$opt.name",
            votes: {
              $let: {
                vars: {
                  // 从voteCounts里找到当前选项对应的统计项
                  matchedVote: {
                    $arrayElemAt: [
                      {
                        $filter: {
                          input: "$voteCounts",
                          cond: { $eq: ["$$this._id", "$$opt._id"] }
                        }
                      },
                      0
                    ]
                  }
                },
                // 如果没找到匹配的统计项,就设为0
                in: { $ifNull: ["$$matchedVote.votes", 0] }
              }
            }
          }
        }
      }
    }
  }
])

逐阶段解释

  1. $lookup阶段:这里用了带子管道的lookup(MongoDB 3.6+支持),比普通lookup更灵活:

    • 先定义变量entryOptions存储当前条目的所有选项
    • 子管道里先对Votes按entryId分组,统计每个选项的投票数
    • 再用$match过滤出只属于当前条目的选项统计结果,最后放到voteCounts数组中
  2. $project阶段:

    • 用$map遍历原始的options数组,给每个选项添加votes字段
    • 用$filter从voteCounts里找到和当前选项_id匹配的统计项,再用$arrayElemAt取出唯一的结果
    • 最后用$ifNull处理没有投票的情况,直接赋值为0

小提示

如果你的Votes集合里,指向选项的字段不是entryId而是optionId(更合理的命名),只需要把$group里的_id: "$entryId"改成_id: "$optionId"就行。

执行这个聚合查询后,就能得到你期望的结果:每个条目下的所有选项都会带上对应的投票数,0票的选项也不会被漏掉。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:30:17