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

如何利用MongoDB聚合框架计算问卷数组答案的统计数据?

MongoDB 问卷答案统计聚合方案

针对你这种数组存储多问题答案的场景,我们可以通过MongoDB聚合框架的多阶段处理实现按问题维度的占比统计,具体管道如下:

假设所有问卷提交文档都在survey_responses集合中,且每个问题的可选答案固定为A、B、C:

db.survey_responses.aggregate([
  // 1. 拆分answers数组,保留每个元素的索引(对应问题编号:索引+1)
  {
    $unwind: {
      path: "$answers",
      includeArrayIndex: "questionIndex"
    }
  },
  // 2. 按问卷ID、问题索引、答案分组,统计每个答案的提交次数
  {
    $group: {
      _id: {
        surveyId: "$surveyId",
        questionIdx: "$questionIndex",
        answer: "$answers.answer"
      },
      count: { $sum: 1 }
    }
  },
  // 3. 按问卷ID、问题索引再次分组,汇总该问题的总提交数和各答案统计
  {
    $group: {
      _id: {
        surveyId: "$_id.surveyId",
        questionIdx: "$_id.questionIdx"
      },
      total: { $sum: "$count" },
      answerStats: { $push: { answer: "$_id.answer", count: "$count" } }
    }
  },
  // 4. 补全未出现的答案(设为0次),并计算占比
  {
    $project: {
      _id: 0,
      surveyId: "$_id.surveyId",
      question: { $concat: ["Question ", { $toString: { $add: ["$_id.questionIdx", 1] } }] },
      stats: {
        $map: {
          input: ["A", "B", "C"],
          as: "opt",
          in: {
            answer: "$$opt",
            percentage: {
              $round: [
                {
                  $multiply: [
                    { $divide: [
                        { $ifNull: [
                            { $arrayElemAt: [
                                "$answerStats.count",
                                { $indexOfArray: ["$answerStats.answer", "$$opt"] }
                              ] },
                            0
                          ] },
                        "$total"
                      ] },
                    100
                  ]
                },
                0 // 保留0位小数,可根据需求调整
              ]
            }
          }
        }
      }
    }
  },
  // 5. 可选:按问题编号排序
  { $sort: { question: 1 } }
])

步骤说明:

  1. $unwind拆分数组:把每个答案拆成独立文档,同时用includeArrayIndex记录该答案对应的问题位置(索引从0开始,对应问题1、2...)。
  2. 第一次$group统计次数:统计同一问卷下,同一问题的每个答案被提交的次数。
  3. 第二次$group汇总问题维度数据:计算每个问题的总提交数,同时把各答案的统计结果整合到数组中。
  4. $project补全选项并计算占比:通过$map遍历所有可选答案,用$indexOfArray匹配已统计的结果,未匹配到的用$ifNull设为0次,再通过除法和乘法计算百分比,最后用$round控制小数位数。
  5. $sort排序:按问题编号顺序输出结果。

输出示例:

[
  {
    "surveyId": "xxxxx",
    "question": "Question 1",
    "stats": [
      { "answer": "A", "percentage": 50 },
      { "answer": "B", "percentage": 40 },
      { "answer": "C", "percentage": 10 }
    ]
  },
  {
    "surveyId": "xxxxx",
    "question": "Question 2",
    "stats": [
      { "answer": "A", "percentage": 60 },
      { "answer": "B", "percentage": 40 },
      { "answer": "C", "percentage": 0 }
    ]
  }
]

如果需要更贴近你期望的纯文本格式,可以在应用层对聚合结果做简单格式化,这比在MongoDB中拼接字符串更灵活。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 17:31:14