文档菜单
文档首页
/ / /
Ruby MongoDB 驱动程序
/

GridFS

本页内容

  • 创建 GridFS 对象 ("Grid::FSBucket")
  • 使用写入流
  • 使用读取流
  • 查找文件元数据
  • 删除文件
  • 与Grid::File对象一起工作
  • 插入文件
  • 查找文件
  • 删除文件

驱动程序提供了一个干净、简单的接口来处理数据库中分块文件的存储,也称为“GridFS”模式。该API允许您使用Grid::File对象或读写流进行操作。

您可以通过调用fs 在数据库上创建一个GridFS对象,可选参数。 fs 返回一个 Grid::FSBucket 对象。

Grid::FSBucket 支持以下选项

选项
描述
:bucket_name
GridFS Bucket的名称。默认为fs
:fs_name
GridFS Bucket的名称。优先于bucket_name。默认为fs
:chunk_size
指定数据库中每个文件块的大小。
:write_concern
上传文件时使用的写关注。请参阅CRUD操作下的写关注部分了解如何处理写关注。
:write
已弃用。与:write_concern相同。
:read
下载文件时使用的读取偏好。

例如,您可以使用特定的读取偏好创建一个GridFS bucket对象

fs_bucket = database.fs( read: { mode: :secondary } )

要使用写流将文件上传到GridFS,您可以打开一个流并直接写入,或者一次性将IO对象的所有内容写入GridFS。

要打开上传流并写入

File.open('/path/to/my-file.txt', 'r') do |file|
fs_bucket.open_upload_stream('my-file.txt') do |stream|
stream.write(file)
end
end

要一次性上传IO对象的所有内容

File.open('/path/to/my-file.txt', 'r') do |file|
fs_bucket.upload_from_stream('my-file.txt', file)
end

写入流支持以下选项

选项
描述
:chunk_size
指定数据库中每个文件块的大小。
:write_concern
上传文件时使用的写入关注点。请参阅写入关注点部分,了解如何使用写入关注点。
:write
已弃用。与:write_concern相同。

这些选项可以作为写入流方法中的最后一个参数提供

fs_bucket.open_upload_stream('my-file.txt', write_concern: {w: 2}) do |stream|
stream.write_concern
# => #<Mongo::WriteConcern::Acknowledged:0x46980201422160 options={:w=>2}>
# ...
end
fs_bucket.upload_from_stream('my-file.txt', file, write_concern: {w: 2})

要从GridFS使用读取流下载文件,您可以直接打开读取流并从中读取,或者一次性下载整个文件。

要打开下载流并从中读取

File.open('/path/to/my-output-file.txt', 'w') do |file|
fs_bucket.open_download_stream(file_id) do |stream|
file.write(stream.read)
end
end

要一次性下载文件并写入IO对象

File.open('/path/to/my-output-file.txt', 'w') do |file|
fs_bucket.download_from_stream(file_id, file)
end

您还可以通过名称和(可选)修订号下载指定的文件。修订号用于区分同名文件,按上传日期排序。传递给open_download_stream_by_name的修订号可以是正数或负数。

File.open('/path/to/my-output-file.txt', 'w') do |file|
fs_bucket.open_download_stream_by_name('my-file.txt', revision: -2) do |stream|
file.write(stream.read)
end
end

要下载指定名称和(可选)修订号的文件的整个内容

File.open('/path/to/my-output-file.txt', 'w') do |file|
fs_bucket.download_to_stream_by_name('my-file.txt', file, revision: -2)
end

读取流支持以下选项

选项
描述
:read
下载文件时使用的读取偏好。

上述某些读取方法将传递这些选项到底层的读取流。请查阅每个方法的API文档,以确定它是否支持特定选项。

您可以从GridFS文件集合中检索包含文件元数据的文档。

fs_bucket.find(filename: 'my-file.txt')

您可以通过ID删除文件。

fs_bucket.delete(file_id)

此对象可以用来包装要插入数据库的文件以及检索到的对象。

创建包含原始数据的文件

file = Mongo::Grid::File.new('I am a file', :filename => 'new-file.txt')

从Ruby File对象创建文件

file = File.open('/path/to/my-file.txt')
grid_file = Mongo::Grid::File.new(file.read, :filename => File.basename(file.path))

更改文件选项,例如块大小,将选项传递给构造函数

file = File.open('/path/to/my-file.txt')
grid_file = Mongo::Grid::File.new(
file.read,
:filename => File.basename(file.path),
:chunk_size => 1024
)

以下是文件支持的所有选项的完整列表。

选项
描述
:chunk_size
设置数据库中每个文件块的大小。
:content_type
为文件设置内容类型。
:filename (必需)
文件名。
:upload_date
文件上传(存储)的日期。

文件可以逐个插入数据库。默认情况下,文件块将插入到fs.chunks集合中,文件元数据将插入到fs.files集合中。

client = Mongo::Client.new([ '127.0.0.1:27017' ], :database => 'music')
file = Mongo::Grid::File.new('I am a file', :filename => 'new-file.txt')
client.database.fs.insert_one(file)

要将文件插入到除 fs 之外名称前缀的集合中,请使用 :fs_name 选项访问文件系统。

client = Mongo::Client.new([ '127.0.0.1:27017' ], :database => 'music')
file = Mongo::Grid::File.new('I am a file', :filename => 'new-file.txt')
client.database.fs(:fs_name => 'grid').insert_one(file)

当驱动器将第一个文件插入到存储桶中时,它将尝试在 fileschunks 集合上创建所需的索引。所需的索引如下

# files collection
{ :filename => 1, :uploadDate => 1 }
# chunks collection
{ :files_id => 1, :n => 1 }, { :unique => true }

注意

如果无法创建索引,例如由于当前用户没有权限,则文件插入将被中止。如果应用程序没有权限创建索引,则数据库管理员必须提前创建所需的索引。

如果存储桶中已有文件,则驱动器不会尝试创建索引,即使它们缺失并且当前用户有权限创建它们。在这种情况下,数据库管理员应尽快创建所需的索引,以确保数据完整性。

文件还可以作为直接插入的替代方式进行流式传输。

client.database.fs.open_upload_stream(filename) do |stream|
stream.write(file)
end

要从数据库中检索文件,请使用适当的过滤器调用 find_one

client = Mongo::Client.new([ '127.0.0.1:27017' ], :database => 'music')
client.database.fs.find_one(:filename => 'new-file.txt') # Returns a Mongo::Grid::File

文件还可以作为直接查找的替代方式进行流式传输。

client.database.fs.open_download_stream(file_id) do |stream|
io.write(stream.read)
end
fs.download_to_stream(file_id, io)

要删除文件,将文件对象传递给 delete_one

client = Mongo::Client.new([ '127.0.0.1:27017' ], :database => 'music')
fs = client.database.fs
file = fs.find_one(:filename => 'new-file.txt')
fs.delete_one(file)

返回

查询缓存