GridFS 是用于存储和检索超过 BSON 文档大小限制 16 MiB 的文件的规范。
注意
GridFS 不支持多文档事务。
GridFS不是将文件存储在单个文档中,而是将文件划分为多个部分或数据段 [],并将每个数据块存储为单独的文档。默认下, 1GridFS使用大小为255 KiB 的数据块;也就是说, GridFS将文件分割为255 KiB 的数据段,但最后一个数据块除外。最后一个数据块的大小以实际需要为准。同样,不大于数据块段的文件仅具有最后一个数据块,仅使用所需的空间以及一些附加元数据。
GridFS 使用两个集合来存储文件。一个集合存储文件数据段,另一集合则存储文件元数据。
当您在GridFS查询文件时,驾驶员会根据需要重新组合数据段。您可以对通过GridFS存储的文件执行范围查询。您还可以访问权限文件任意部分的信息,例如“跳”到视频或音频文件的中间。
GridFS不仅可用于存储超过16 MiB 的文件,还可存储您要访问权限的任何文件,而无需将整个文件加载到内存中。另请参阅 何时使用GridFS。
何时使用 GridFS
使用GridFS存储大于 16MiB 的文件。
某些情况下,在 MongoDB 数据库中存储大文件的效率可能比在系统级文件系统上更有效。
如果文件系统限制目录中的文件数量,则可以使用 GridFS 根据需要存储任意数量的文件。
如果要访问权限大文件的部分内容而不将整个文件加载到内存中,请使用GridFS。
如果您希望在多个系统和设施之间保持文件和元数据同步和部署,请使用GridFS。借助地理上分布式的副本集, MongoDB将文件及其元数据分发到多个设施中的
mongod实例。
如果需要原子更新整个文件的内容,请勿使用 GridFS。作为替代方案,您可以存储每个文件的多个版本,并在元数据中指定文件的当前版本。您可以在上传新版本的文件后,对指示“最新”状态的元数据字段进行原子更新,并在之后根据需要删除以前的版本。
如果您的文件均小于16 MiB BSON文档大小限制,请考虑将每个文件存储在单个文档中,而不是使用GridFS。使用 BinData数据类型存储二进制数据。有关使用 BinData 的详细信息,请参阅驱动程序文档。
使用 GridFS
使用 GridFS 存储和检索文件有如下两种方法:
MongoDB 驱动程序。有关将 GridFS 与驱动程序一起使用的信息,请参阅驱动程序文档。
mongofiles命令行工具。请参阅mongofiles参考文档。
GridFS 集合
GridFS 将文件存储在两个集合中:
GridFS 通过为每个集合添加一个存储桶名称前缀,从而将这些集合放置在一个通用存储桶中。默认情况下,GridFS 使用两个集合以及带名为 fs 的存储桶:
fs.filesfs.chunks
您可以选择不同的存储桶名称,也可以在单个数据库中创建多个存储桶。完整的集合名称(包括存储桶名称)受命名空间长度限制的约束。
chunks 集合
chunks [1] 集合中的每个文档都代表文件中的不同数据段,如 GridFS 中所示。此集合中的文档具有以下形式:
{ "_id" : <ObjectId>, "files_id" : <ObjectId>, "n" : <num>, "data" : <binary> }
chunks 集合中的文档包含以下字段:
chunks._id该数据段的唯一 ObjectId。
chunks.data该数据段的有效负载为 BSON
Binary类型。
files 集合
files 集合中的每个文档均代表 GridFS 中的一个文件。
{ "_id" : <ObjectId>, "length" : <num>, "chunkSize" : <num>, "uploadDate" : <timestamp>, "md5" : <hash>, "filename" : <string>, "contentType" : <string>, "aliases" : <string array>, "metadata" : <any>, }
files 集合中的文档包含以下部分或全部字段:
files.chunkSize每个数据块的大小(以字节为单位)。GridFS 将文档划分为大小为
chunkSize的数据块,但最后一个除外,它的大小视需要而定。默认大小为 255 kibibytes (KiB)。
files.md5已弃用
FIPS 140-2 禁止使用 MD5 算法。MongoDB 驱动程序已弃用 MD5 支持,并将在未来版本中删除 MD5 生成。需要文件摘要的应用程序应在 GridFS 外部实施文件摘要,并将其存储在
files.metadata中。命令返回的完整文件的
filemd5MD5 哈希值。该值的类型为String。
files.contentType已弃用
可选。GridFS 文件的有效 MIME 类型。仅供应用程序使用。
使用
files.metadata来存储与 GridFS 文件的 MIME 类型相关的信息。
files.aliases已弃用
可选。别名字符串数组。仅供应用程序使用。
使用
files.metadata存储别名信息。
GridFS Indexes
GridFS在每个chunks 和files 集合上使用索引以效率。符合GridFS规范的驱动程序会自动创建这些索引。您还可以创建其他索引来适应您的应用程序。
chunks 索引
GridFS 在 chunks 集合上使用了一个唯一的复合索引,该索引使用了 files_id 和 n 字段。这可支持高效地检索数据段,如以下示例所示:
db.fs.chunks.find( { files_id: myFileID } ).sort( { n: 1 } )
符合GridFS规范的驱动程序会在写入操作之前自动确保该索引存在。有关GridFS应用程序的特定行为,请参阅相关驾驶员文档。
如果此索引不存在,则可使用 mongosh 发出以下操作来创建该索引:
db.fs.chunks.createIndex( { files_id: 1, n: 1 }, { unique: true } );
files 索引
GridFS 在 files 集合上使用了一个基于 filename 和 uploadDate 字段的索引。此索引可支持高效检索文件,如以下示例所示:
db.fs.files.find( { filename: myFileName } ).sort( { uploadDate: 1 } )
符合GridFS规范的驱动程序会在写入操作之前自动确保该索引存在。有关GridFS应用程序的特定行为,请参阅相关驾驶员文档。
如果此索引不存在,则可使用 mongosh 发出以下操作来创建该索引:
db.fs.files.createIndex( { filename: 1, uploadDate: 1 } );
| [1] | (1, 2) 在 GridFS 上下文中使用数据段一词与分片上下文中数据段一词的使用无关。 |
对 GridFS 进行分片
GridFS有两个需要考虑的集合: files和chunks 。
chunks Collection
要对 chunks 集合进行分片,请使用 { files_id : 1, n : 1
} 或 { files_id : 1 } 作为分片键索引。files_id 是一个单调变化的 ObjectID。
对于不运行filemd5 来验证上传成功的MongoDB驱动程序,您可以对chunks 集合使用哈希分片。
如果MongoDB驾驶员运行filemd5 ,则无法使用哈希分片。有关详细信息,请参阅 SERVER-9888 。
files Collection
files 集合较小,仅包含元数据。GridFS 所需的任何键都不适合在分片环境中均匀分布。将 files 保持为未分片可让所有文件元数据文档驻留在一个分片上。
如果必须对 files 集合进行分片,请使用 _id 字段,可能要与应用程序字段结合使用。