MongoDB 聚合:将二维数组映射为各子数组长度构成的一维数组

2次阅读

MongoDB 聚合:将二维数组映射为各子数组长度构成的一维数组

本文介绍如何使用 mongodb 聚合管道(特别是 `$map` 与 `$size`)将存储用户答题结果的二维数组(如 `results: [[“u1″,”u2”], [], [“u3″,”u4″,”u5”], [“u6”]]`)高效转换为对应子数组长度组成的一维数组(如 `[2, 0, 3, 1]`),完全适配动态题型(2–5 个选项)。

在构建在线测验系统时,常将用户选择以二维数组形式结构化存储:外层数组每个位置对应一个选项,内层数组存放选中该选项的用户 ID。例如:

{"results": [["10938381", "10938382"], [], ["10938383", "10938384", "10938385"], ["10938386"]] }

目标是将其聚合为各选项被选次数的统计数组 [2, 0, 3, 1] —— 这一需求 不依赖固定长度,必须兼容 2 至 5 个选项的任意配置。

MongoDB 原生支持函数式数组变换,推荐使用 $map 配合 $size 实现零侵入、高性能的转换:

Model.aggregate([{     $project: {       results: {         $map: {           input: "$results",           in: { $size: "$$this"}         }       }     }   } ]);
  • $map 遍历 “$results” 的每一项(即每个用户 ID 子数组);
  • $$this 指代当前遍历的子数组;
  • $size 直接返回该子数组的元素个数(空数组返回 0);
  • 最终输出字段 results 被重写为纯数字数组,长度与原始外层数组一致。

优势说明

  • ✅ 完全动态:无需预设子数组数量,自动适配任意长度的 results;
  • ✅ 高效可靠:单阶段完成,无 $unwind 导致的文档膨胀,性能稳定;
  • ✅ 兼容 Mongoose:可直接在 .aggregate() 链中调用,返回结果与原 schema 字段名一致;
  • ✅ 可扩展:后续可轻松叠加 $addFields 或 $group 进行全局统计(如总答题人数、最高选中率等)。

⚠️ 注意事项

  • 确保 results 字段始终为数组类型(可在 Schema 中定义 results: [[String]]);
  • 若存在 null 或缺失 results 字段,建议前置 $ifNull 处理,例如:input: {$ifNull: [“$results”, []] };
  • 在生产环境聚合前,建议使用 .explain(“executionStats”) 验证性能,尤其当集合量级较大时。

该方案简洁、健壮且符合 MongoDB 的声明式设计哲学,是处理此类“数组维度降维统计”问题的标准实践。

admin
版权声明:本站原创文章,由 admin 2026-01-15发表,共计1018字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
4ac55428134b966183879b4b26b86197
text=ZqhQzanResources