
本文介绍如何使用 mongodb 聚合管道(特别是 `$map` 和 `$size`)将存储答题结果的二维数组(如 `results: [["u1","u2"], [], ["u3","u4","u5"], ["u6"]]`)高效转换为对应子数组长度的一维数组(如 `[2, 0, 3, 1]`),完全适配动态题干选项数量(2–5 个)。
在基于 MongoDB 构建的在线测验系统中,常采用二维数组结构存储用户选择行为:外层数组每个位置对应一个预设答案选项,内层数组则存放选中该选项的用户 ID 列表。例如:
{ "results": [["10938381", "10938382"], [], ["10938383", "10938384", "10938385"], ["10938386"]] }目标是将其聚合为统计维度——即每个选项被选择的次数,生成形如 { "results": [2, 0, 3, 1] } 的结果。关键在于:不依赖固定长度,支持任意长度的外层数组(2–5 项)。
✅ 推荐方案:$map + $size
使用 $map 遍历 results 数组的每一项(即每个子数组),对每项应用 $size 运算符获取其元素个数,最终输出长度一致的新数组:
所谓数组,就是相同数据类型的元素按一定顺序排列的集合,就是把有限个类型相同的变量用一个名字命名,然后用编号区分他们的变量的集合,这个名字称为数组名,编号称为下标。组成数组的各个变量称为数组的分量,也称为数组的元素,有时也称为下标变量。数组是在程序设计中,为了处理方便, 把具有相同类型的若干变量按有序的形式组织起来的一种形式。这些按序排列的同类数据元素的集合称为数组。 数组应用&二维数组目录 1. 数组的简单应用2. 数组排序3. 数组查找4. 数组的使用思想5. 查表法6. 二维数组7. 数组综合
YourModel.aggregate([
{
$project: {
results: {
$map: {
input: "$results",
in: { $size: "$$this" }
}
}
}
}
]);- $map 是 MongoDB 中专用于数组映射的表达式操作符;
- input: "$results" 指定待处理的源数组;
- in: { $size: "$$this" } 表示对当前遍历项(用 $$this 引用)计算其大小;
- 该操作天然支持变长数组,无论 results 包含 2、3、4 或 5 个子数组,均能正确输出等长的整数数组。
⚠️ 注意事项
- 确保 results 字段始终为数组类型(空数组 [] 也合法),若存在 null 或缺失字段,$size 将返回 0(MongoDB 行为),建议在写入时做数据校验;
- 若需同时保留原始 results 并新增统计字段(如 voteCounts),可改用别名投影:
{ $project: { voteCounts: { $map: { input: "$results", in: { $size: "$$this" } } } } } - 在 Mongoose 中调用时,确保模型已正确定义 results 的 Schema 类型(推荐 [[String]] 或 Array(Array(String)))以获得 TypeScript 支持与运行时校验。
该方案简洁、高效、无副作用,无需 $unwind/$group 等重量级阶段,适用于高并发实时统计场景,是处理此类“数组长度映射”需求的标准实践。









