$match 必须前置,否则导出卡死、内存爆满、超时失败;时间范围须用 isodate,多条件合并进一个 $match;导出需显式启用 allowdiskuse: true;禁用 $skip+$limit 深分页;优先选扩展 json 格式导出。

$match 必须前置,否则导出根本跑不动
导出报表卡死、内存爆满、超时失败——90% 是因为 $match 没放在第一阶段。MongoDB 不会重排阶段顺序,$match 放在 $unwind 或 $group 后面,等于把全量文档(比如 50 万条)全加载进内存再过滤。实测:某考勤报表从 12 秒 → 480ms,仅靠把 $match 移到开头 + 给 semester 和 section 加复合索引。
- 时间范围必须用
ISODate("2026-08-01"),别写字符串"2026-08-01",否则索引失效 - 多个条件合并进一个
$match,不要拆成两个$match阶段 - 如果要按嵌套数组字段(如
atndnc.date)过滤,$match必须在$unwind之后——但这种情况极少,先确认外层字段是否真不能覆盖需求
导出前必须加 allowDiskUse: true
聚合结果超过 100MB 或分组后文档数 >10 万,db.collection.aggregate() 默认直接报错 Exceeded memory limit。这不是配置问题,是 WiredTiger 引擎硬限制。
Miller (mlr) 是一个命令行工具,用于查询、整形和重新格式化名称索引数据,如 CSV、TSV、JSON 和 JSON Lines。它将 awk、sed、cut、join 和 sort 的功能整合到一个专为结构化数据处理而构建的单一工具中。
- Compass 导出 CSV/JSON 时自动启用磁盘,但代码调用(如 Node.js 驱动)必须显式传参:
{ allowDiskUse: true } - 磁盘导出不等于无代价:I/O 成为瓶颈,尤其在云服务器小磁盘上,建议监控
mongod进程的磁盘读写延迟 - 别用
$skip+$limit做深分页导出(如跳过 10 万条),改用游标式导出:{ _id: { $gt: ObjectId("...") } }
导出格式选 JSON,别碰 CSV
CSV 看起来方便,但会丢失 BSON 类型:ObjectId 变成字符串、NumberLong 被截断、日期变成毫秒数或空。导出后无法原样还原,二次分析极易出错。
- Compass 导出 JSON 时,默认用「扩展 JSON」,保留所有类型信息,直接可用
- 若需跨语言解析(如 Python pandas),选「规范扩展 JSON」,它用
{"$oid": "..."}这类结构,各语言驱动都支持反序列化 - 导出大文件(>500MB)时,提前确认目标路径磁盘空间,MCP Server 默认导出目录在
~/.mongodb/mongodb-mcp/exports(Linux/macOS)
真正难的是分组键设计和空值处理
导出内容对不上业务口径,往往不是语法错,而是 $group 的 _id 漏了维度,或 $unwind 后没清掉 null。比如学生出勤率报表,_id: { rollno: "$rollno" } 会把同名不同班的学生合并;$unwind: "$atndnc" 不加 preserveNullAndEmptyArrays: true,遇到空数组直接中断管道。










