Overview
在本指南中,您可以学习;了解如何使用GridFS在MongoDB中存储和检索大文件。 GridFS规范描述了如何在存储文件时将文件分割为数据段,以及在检索文件时如何重新组合这些文件。 GridFS的Ruby驱动实施是一个用于管理文件存储的操作和组织的抽象。
如果文件大小超过16 MB 的BSON文档大小限制,请使用GridFS 。 有关GridFS是否适合您的使用案例的更多详细信息,请参阅MongoDB Server手册中的 GridFS 。
以下部分描述了 GridFS 操作以及如何执行这些操作。
GridFS 的工作原理
GridFS 在存储桶中组织文件,存储桶是一组包含文件数据段及其描述信息的MongoDB 集合。存储桶包含以下集合,使用 GridFS 规范中定义的约定命名:
chunks
集合存储二进制文件数据段。files
集合存储文件元数据。
当您创建新的GridFS存储桶时,驾驶员会创建fs.chunks
和fs.files
集合,除非您在Mongo::Database#fs
方法选项中指定不同的名称。该驾驶员还会在每个集合上创建一个索引,以确保有效检索文件和相关元数据。如果GridFS存储桶不存在,则驾驶员仅在执行第一次写入操作时才会创建该存储桶。仅当索引不存在且存储桶为空时,驾驶员才会创建索引。有关GridFS索引的更多信息,请参阅MongoDB Server手册中的GridFS索引。
使用GridFS存储文件时,驾驶员会将文件分割成较小的数据段,每个数据段由 chunks
集合中的单独文档表示。它还在 files
集合中创建一个文档,其中包含文件ID、文件名和其他文件元数据。您可以从内存或流上传文件。下图显示了GridFS在上传到存储桶时如何拆分文件。

在检索文件时,GridFS 从指定存储桶上的 files
集合中获取元数据,并使用该信息通过 chunks
集合中的文档重建文件。您可以将文件读取到内存中,或者将其输出到流。
创建 GridFS 存储桶
要从GridFS存储或检索文件,请对 Mongo::Database
实例调用 fs
方法,以创建GridFS存储桶。您可以使用 FSBucket
实例对存储桶中的文件执行读取和写入操作。
bucket = database.fs
要创建或引用默认名称 fs
以外的存储桶,请将该存储桶名称作为可选参数传递给 fs
方法,如以下示例所示:
custom_bucket = database.fs(database, bucket_name: 'files')
上传文件
upload_from_stream
方法读取上传流的内容并将其保存到 GridFSBucket
实例中。
您可以传递 Hash
作为可选参数,以配置数据块大小或包含其他元数据。
以下示例将文件上传到 FSBucket
并为上传文件指定元数据:
metadata = { uploaded_by: 'username' } File.open('/path/to/file', 'rb') do |file| file_id = bucket.upload_from_stream('test.txt', file, metadata: metadata) puts "Uploaded file with ID: #{file_id}" end
检索文件信息
在本部分中,您可以了解如何检索存储在 GridFS 存储桶的 files
集合的文件元数据。元数据包含所引用文件的相关信息,包括:
文件的
_id
文件的名称
文件大小
上传日期和时间
您可以在其中存储任何其他信息的
metadata
文档
要学习;了解有关可从files
集合检索的字段的更多信息,请参阅MongoDB Server手册中的GridFS文件集合文档。
要从GridFS存储桶检索文件,请对 FSBucket
实例调用 find
方法。 以下代码示例从GridFS存储桶中的所有文件中检索并打印文件元数据:
bucket.find.each do |file| puts "Filename: #{file.filename}" end
要学习;了解有关查询MongoDB 的更多信息,请参阅 检索数据。
下载文件
download_to_stream
方法下载文件的内容。
要通过文件_id
下载文件,请将 _id
传递给该方法。 download_to_stream
方法将文件内容写入提供的对象。以下示例通过文件_id
下载文件:
file_id = BSON::ObjectId('your_file_id') File.open('/path/to/downloaded_file', 'wb') do |file| bucket.download_to_stream(file_id, file) end
如果知道文件名称但不知道其 _id
,则可以使用 download_to_stream_by_name
方法。以下示例下载名为 mongodb-tutorial
的文件:
File.open('/path/to/downloaded_file', 'wb') do |file| bucket.download_to_stream_by_name('mongodb-tutorial', file) end
注意
如果多个文档具有相同的 filename
值, GridFS将获取具有给定名称(由 uploadDate
字段确定)的最新文件。
删除文件
使用 delete
方法从存储桶中删除文件的集合文档和关联的数据段。 您必须用文件的 _id
字段而不是文件名来指定文件。
以下示例通过 _id
删除文件:
file_id = BSON::ObjectId('your_file_id') bucket.delete(file_id)
注意
delete
方法一次仅支持删除一个文件。 要删除多个文件,请从存储桶中检索文件,提取要删除的文件中的_id
字段,然后将每个值分别传递给delete
方法。
API 文档
要学习;了解有关使用GridFS存储和检索大文件的更多信息,请参阅以下API文档: