GridFS 是用于存储和检索超过 BSON 文档大小限制 16 MiB 的文件的规范。
注意
GridFS 不支持多文档事务。
GridFS不是将文件存储在单个document中,而是将文件划分为多个部分或数据块[1],并将每个数据块存储为单独的document。默认下, GridFS使用大小为 255 KiB 的数据块;也就是说, GridFS将文件分割为 255 KiB 的数据块,但最后一个数据块除外。最后一个数据块的大小以实际需要为准。同样,不大于数据块段的文件仅具有最后一个数据块,仅使用所需的空间以及一些附加元数据。
GridFS 使用两个集合来存储文件。一个集合存储文件数据段,另一集合则存储文件元数据。
当您在GridFS查询文件时,驱动程序会根据需要重新组合数据块。您可以对通过GridFS存储的文件执行范围查询。您还可以访问权限文件任意部分的信息,例如“跳”到视频或音频文件的中间。
GridFS 不仅可存储超过 16 MiB 的文件,还可存储您想要访问的任何文件,同时无需将整个文件加载到内存中。另请参阅何时使用 GridFS。
何时使用 GridFS
使用GridFS存储大于 16 MiB 的文件。
某些情况下,在 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已弃用
MD5 算法被 FIPS140 -2 55禁止。 MongoDB驱动程序已弃用 MD 支持,并将在未来版本中删除MD 生成。需要文件摘要的应用程序应在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 字段,可能要与应用程序字段结合使用。