自管理部署的 GridFS
GridFS 是一种用于存储和检索超过 BSON 文档大小限制(16 MB)的文件的规范。
注意
GridFS 不支持 多文档事务。
GridFS不是将文件存储在单个文档中,而是将文件分割成多个部分或块[1],并将每个块作为一个独立的文档存储。默认情况下,GridFS使用默认块大小为255 KB;也就是说,GridFS将文件分割成255 KB的块(最后一块除外)。最后一块的大小仅根据需要。类似地,文件大小不超过块大小的文件只有一个最终块,仅使用所需的空间加上一些附加元数据。
GridFS使用两个集合来存储文件。一个集合存储文件块,另一个存储文件元数据。《GridFS 集合部分详细描述了每个集合。
当你查询GridFS以获取文件时,驱动程序将根据需要重新组装块。你可以对通过GridFS存储的文件执行范围查询。你还可以访问文件中的任意部分的信息,例如“跳过”视频或音频文件的中间部分。
GridFS不仅适用于存储超过16 MB的文件,而且适用于存储任何你想要访问而不必将整个文件加载到内存中的文件。请参阅何时使用GridFS。
何时使用GridFS
在MongoDB中,使用GridFS来存储超过16 MB的文件。
在某些情况下,在MongoDB数据库中存储大文件可能比在系统级文件系统中存储更有效。
如果你的文件系统限制目录中的文件数量,你可以使用GridFS来存储所需数量的文件。
当你想从大文件的各个部分访问信息而不必将整个文件加载到内存中时,你可以使用GridFS来调用文件的部分而不必读取整个文件到内存中。
当您希望将文件和元数据自动同步和部署到多个系统和设施时,可以使用GridFS。当使用地理分布副本集时,MongoDB可以将文件及其元数据自动分发到多个
mongod实例和设施。
如果您需要原子性地更新整个文件的内容,则不要使用GridFS。作为替代方案,您可以为每个文件存储多个版本,并在元数据中指定文件的当前版本。您可以在上传文件的新版本后,通过原子更新来更新表示“最新”状态的元数据字段,并在需要时删除以前的版本。
此外,如果您的文件都小于16 MB的BSON文档大小限制,可以考虑将每个文件存储在一个单独的文档中,而不是使用GridFS。您可以使用BinData数据类型来存储二进制数据。有关使用BinData的详细信息,请参阅您的驱动程序文档。
使用GridFS
要使用GridFS存储和检索文件,请使用以下方法之一
一个MongoDB驱动程序。有关使用驱动程序与GridFS的信息,请参阅驱动程序文档。
命令行工具
mongofiles。有关详细信息,请参阅mongofiles参考。
GridFS 集合
GridFS 将文件存储在两个集合中
chunks集合存储二进制块。详细信息请参见chunks集合。files集合存储文件的元数据。详细信息请参见files集合。
GridFS 通过在每个集合名称前添加桶名称来将这些集合放置在公共桶中。默认情况下,GridFS 使用名为 fs 的桶中的两个集合
fs.filesfs.chunks
您可以选择不同的桶名称,以及在单个数据库中创建多个桶。完整的集合名称,包括桶名称,受 命名空间长度限制。
chunks 集合
chunks 集合中的每个文档代表 GridFS 中表示的文件的一个单独块。此集合中的文档具有以下形式
{ "_id" : <ObjectId>, "files_id" : <ObjectId>, "n" : <num>, "data" : <binary> }
chunks 集合中的文档包含以下字段
chunks._id分块的唯一ObjectId。
chunks.data分块的有效载荷,以BSON
Binary类型。
文件集合 files
文件集合中的每个文档代表一个 GridFS 中的文件。
{ "_id" : <ObjectId>, "length" : <num>, "chunkSize" : <num>, "uploadDate" : <timestamp>, "md5" : <hash>, "filename" : <string>, "contentType" : <string>, "aliases" : <string array>, "metadata" : <any>, }
文件集合中的文档包含以下字段之一或全部:
files.md5已弃用
MD5算法被FIPS 140-2禁止。MongoDB驱动程序弃用MD5支持,并在未来版本中移除MD5生成。需要文件摘要的应用程序应在GridFS外部实现它,并存储在
files.metadata中。filemd5命令返回的完整文件的MD5哈希。此值具有
String类型。
files.contentType已弃用
可选。GridFS文件的合法MIME类型。仅限应用程序使用。
使用
files.metadata存储与GridFS文件MIME类型相关的信息。
files.aliases已弃用
可选。一个别名字符串数组。仅用于应用。
使用
files.metadata存储与GridFS文件MIME类型相关的信息。
GridFS 索引
GridFS 使用每个chunks和files集合的索引以提高效率。遵守驱动程序的GridFS 规范会自动创建这些索引以方便使用。您还可以根据应用程序的需求创建任何其他索引。
《chunks 索引》
GridFS 使用在 chunks 集合上基于 files_id 和 n 字段的 唯一、组合索引。这允许高效地检索块,如下例所示
db.fs.chunks.find( { files_id: myFileID } ).sort( { n: 1 } )
符合 GridFS 规范 的 mongosh: 将在读写操作之前自动确保该索引存在。请参阅相关驱动程序的文档,以了解您的 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 规范 的 mongosh: 将在读写操作之前自动确保该索引存在。请参阅相关驱动程序的文档,以了解您的 GridFS 应用程序的具体行为。
如果此索引不存在,您可以使用以下操作通过 mongosh: 创建它
db.fs.files.createIndex( { filename: 1, uploadDate: 1 } );
| [1] | (1, 2) 在 GridFS 上下文中使用术语 chunks 与在分片上下文中使用术语 chunks 无关。 |
分片 GridFS
在 GridFS 中,需要考虑两个集合 - files 和 chunks。
chunks 集合
要分片 chunks 集合,请使用 { files_id : 1, n : 1 } 或 { files_id : 1 } 作为分片键索引。`files_id` 是一个 ObjectId 并且单调变化。
对于不运行 filemd5 以验证成功上传的 MongoDB 驱动程序,您可以为 chunks 集合使用 哈希分片。
如果MongoDB驱动程序运行了filemd5命令,您不能使用哈希分片。有关详细信息,请参阅SERVER-9888.
files 集合
files 集合很小,只包含元数据。GridFS所需的所有键在分片环境中都无法均匀分布。保持files未分片,可以让所有文件元数据文档都位于一个分片上。
如果您必须分片files集合,请使用_id字段,可能还需要结合一个应用程序字段。