如何用单条MongoDB聚合查询统计多选题各选项频次?
实现多选题作答统计的MongoDB聚合查询
当然可以通过单条聚合查询实现你需要的统计结果,以下是完整的查询语句及分步说明:
完整聚合查询代码
db.test.aggregate([ // 转换题目字段为统一格式的数组 { $project: { questions: [ { key: 1, value: "$Q2_1" }, { key: 2, value: "$Q2_2" }, { key: 3, value: "$Q2_3" } ] } }, // 展开数组,每道题生成单独文档 { $unwind: "$questions" }, // 按题目编号分组统计核心指标 { $group: { _id: "$questions.key", abs: { $sum: { $cond: [{ $eq: ["$questions.value", 1] }, 1, 0] } }, base: { $sum: { $cond: [{ $ne: ["$questions.value", -77] }, 1, 0] } } } }, // 计算占比并整理输出字段 { $project: { _id: 0, key: "$_id", abs: 1, base: 1, perc: { $divide: ["$abs", "$base"] } } }, // 按题目编号升序排序 { $sort: { key: 1 } } ])
各阶段说明
$project 转换字段格式
将每个文档中的Q2_1/Q2_2/Q2_3字段转换为包含key(题目编号)和value(作答值)的数组,把分散的题目字段统一成可批量处理的结构。$unwind 展开数组
将数组拆分为单个文档,每道题对应一条独立文档,为后续分组统计做准备。$group 分组统计
按题目key分组,使用$cond条件判断实现精准计数:abs:统计作答值为1的数量(选择该题的有效人数)base:统计作答值不为-77的数量(看到该题的总人数)
$project 整理输出结构
移除默认的_id字段,将分组ID重命名为key,并通过$divide计算选择占比perc。$sort 排序结果
按key升序排列,确保输出顺序与你期望的结果一致。
运行该查询后,会直接返回你需要的统计数组:
[ { "key": 1, "abs": 2, "base": 3, "perc": 0.6666666666666666 }, { "key": 2, "abs": 1, "base": 2, "perc": 0.5 }, { "key": 3, "abs": 2, "base": 4, "perc": 0.5 } ]
扩展提示
如果后续新增题目(如Q2_4),只需在$project阶段的questions数组中添加{ key: 4, value: "$Q2_4" }即可,无需修改其他逻辑。
内容的提问来源于stack exchange,提问作者elajdsha
相关产品推荐
相关产品推荐

