直接写入超16MB文档会报错“Payload document size is larger than maximum of 16MB”或BsonMaximumSizeExceededException,这是MongoDB底层BSON协议的硬性拦截,请求在网络层即被拒绝;GridFS虽可存储大文件,但fs.files和fs.chunks结构固定、不可索引且不支持聚合操作,必须通过独立元数据集合(含file_id关联fs.files._id)承载可查询字段并建索引,才能实现聚合、排序等业务查询。
遇到 Payload document size is larger than maximum of 16MB 或 BsonMaximumSizeExceededException,说明你正试图插入或更新一个超限文档——这不是配置问题,也不是驱动 bug,而是 MongoDB 底层 BSON 协议的硬性拦截。它会在网络层就拒绝请求,根本不会进入存储引擎。
GridFS 把文件切进 fs.files(元信息)和 fs.chunks(二进制块),这两个集合结构固定、字段不可索引:
fs.files.filename 是字符串,但默认没建索引;uploadDate 是 ISODate,也不含业务语义字段(如 deviceId、status)fs.chunks.data 是 BinData 类型,聚合管道里连 $match 都不支持,更别说 $group 或 $sort
fs.chunks 执行聚合会直接报错:errmsg: "cannot use $group in fs.chunks" —— 这是设计限制,不是权限或语法问题核心是把“存”和“查”拆开:用 GridFS 存原始大 JSON,用独立集合存可索引、可聚合的业务字段,并通过 file_id 关联。
file_id: ObjectId(""),且值要与 fs.files._id 完全一致,否则 $lookup 关联失败errorCount、durationMs、deviceId、timestamp,别把整个 JSON 结构复制进去db.large_docs_meta.createIndex({ deviceId: 1, timestamp: -1 })
拆成多个子文档不是万能解,只适用于逻辑上可分割、且查询模式固定的场景:
db.comments.find({ postId: "abc" }))totalCommentCount)不同步 —— 或者自己加双写逻辑如果业务需要按时间范围对“十年日志”统一排序、分页跳转到第 10001 条,或者要实时计算 errorRate = errorCount / totalCount,那拆文档反而让问题更重:MongoDB 不支持跨文档数组展开后统一排序。