MongoDB 5.0+ 中必须优先使用 timeseries 集合处理时序数据,需显式调用 createCollection 创建,timeField 必须为非空 Date 类型,granularity 仅支持 seconds/minutes/hours 且不可更改,TTL 索引须建 metaField 与 timeField 复合索引,且时序集合不支持事务。
直接说结论:MongoDB 5.0+ 中,**优先用 timeseries 集合**,而不是手写分桶逻辑或单文档单点存储——它不是“可选项”,而是针对时序场景的底层优化基础设施。但必须按规则创建,否则等于白用。
createCollection
你往普通集合里插一万条带 ts 字段的文档,它也永远不是时序集合。MongoDB 不会自动识别、升级或转换。
db.createCollection("sensors", { timeseries: { timeField: "ts", metaField: "device", granularity: "minutes" } })
timeField 必须是 Date 类型,且每条文档都得有、不能为 null 或缺失metaField 是可选字符串字段(比如 "device"),用于后续按设备/传感器类型高效分组查询timeField、metaField 或 granularity,也不能把已有集合转成时序集合granularity 选错会让压缩率暴跌 3–5 倍它不是“你想查多细就设多细”,而是告诉 MongoDB “同一物理 bucket 里的时间戳大致差多少”。只接受 seconds、minutes、hours 三个值。
minutes,不是 seconds;否则 bucket 内部稀疏,压缩失效minutes 适合温湿度、电表读数等 ≥10 秒间隔、常按小时/天聚合的场景seconds 仅适用于真需要亚秒级窗口聚合(如高频金融 tick),且能承受更高磁盘开销$dateTrunc 照常工作),但底层组织方式崩了{ metaField: 1, timeField: 1 } 复合索引只在 ts 上建单字段 TTL 索引,清理效率极低:MongoDB 会扫整条时间线,无法按设备粒度推进。
db.sensors.createIndex({ device: 1, ts: 1 }, { expireAfterSeconds: 2592000 })(30 天)device 分批执行,降低单次操作压力最容易被忽略的一点:时序集合不支持事务——如果你的业务流程强依赖跨集合原子性(比如同时写传感器数据 + 更新设备状态),就得在应用层兜底或改用普通集合+分桶设计。别等到上线才发现。