GridFS适合存储超过16MB限制的大文件,如GB级音视频、PDF等;小文件(如10MB)也必须用GridFS,否则写入失败。它通过分块(默认255KB/chunk)和元数据分离实现,规避单文档上限,同时保障原子性、并发安全与范围读取能力。
GridFS 适合存什么大小的文件
MongoDB 文档有 16MB 上限,
字段直接存二进制会很快撞到这个限制。超过几 MB 的图片、PDF、音视频,用普通字段存不是报错就是被截断——错误信息通常是
或写入后读出来长度不对。
GridFS 不是“另一个存储引擎”,而是客户端侧的分块协议:自动把大文件切为默认 255KB 的
文档,元数据存在
集合。只要单个 chunk 不超 16MB(它绝不会),整体文件可以是 GB 级。
小文件(BinData 更快,少一次集合查询
中等文件(100KB–10MB):两者都行,但 GridFS 提供流式读写和部分读取能力
大文件(>10MB):必须用 GridFS,否则写不进去
为什么不能只靠 application 层分片再存多个文档
有人试过手动把文件切成 buffer 数组,每个存一个文档,加个
字段排序。这看似绕开了 GridFS,实际埋了三个坑:
原子性丢失:上传中途失败,数据库里残留不完整碎片,application 得自己清理
并发读取风险:多个 client 同时读同一个“伪文件”,可能拿到不同版本的 chunk 组合
缺失范围读支持:想只下载 PDF 的第 3 页?得把所有 chunk 拉下来再拼,没法像 GridFS 那样用
/
或
/
参数直接定位
GridFS 的
和
内置了这些逻辑,不是语法糖,是协议级保障。
Node.js 里用
驱动操作 GridFS 的关键点
新版驱动(v4+)把 GridFS API 收进了
类,不是挂载在 db 对象上。容易漏掉初始化步骤,导致调用
报
。
go语言参考手册 中文CHM版
Go 是一个开源的编程语言,它能让构造简单、可靠且高效的软件变得容易。本文给大家带来Go参考手册,需要的可以来下载! Go是从2007年末由Robert Griesemer, Rob Pike, Ken Thompson主持开发,后来还加入了Ian Lance Taylor, Russ Cox等人,并最终于2009年11月开源,在2012年早些时候发布了Go 1稳定版本。现在Go的开发已经是完全开放的,并且拥有一个活跃的社区。 Go 语言特色 简洁、快速、安全 并行、有趣、开源 内存管理、v数组安全、编译
下载
正确姿势:
必须显式传,否则默认用
,但你建的集合如果是
,就查不到
上传时
是必填元数据,不然
查不到;
要手动设,不会自动推断
删除文件用
传
,不是
—— 后者只删
集合,chunk 还在,磁盘白占
GridFS 的性能和运维隐性成本
它解决了“存不下”的问题,但没解决“读得慢”或“备份麻烦”。每个文件变多条文档,索引体积涨、oplog 压力大、mongodump 备份时间明显变长。
高频小文件(比如用户头像缩略图):考虑合并存到对象存储(S3/MinIO),Mongo 只存 URL
需要全文检索或按内容查文件:GridFS 不支持,得额外抽文本建索引,不如直接存 Elasticsearch
跨集群迁移时:
和
集合必须一起导,漏一个就文件损坏
真正卡住人的往往不是“怎么用”,而是“什么时候不该用”——尤其当团队开始往里面塞日志、监控快照、临时导出文件的时候。
BinDataDocument too largechunksfilesseqskiplimitstartendfs.openDownloadStream()fs.openUploadStream()mongodbGridFSBucketopenUploadStreamTypeError: fs.openUploadStream is not a functionconst { MongoClient, GridFSBucket } = 'mongodb';
const client = new MongoClient(uri);
await client.connect();
const db = client.db('mydb');
const fs = new GridFSBucket(db, {
bucketName: 'uploads' // 默认是 'fs',改名要前后一致
});
bucketNamefsuploads.filesfilenamefind()contentTypedelete()_idremove()fileschunksfiles