对于 AI 代理:可在 https://www.mongodb.com/zh-cn/docs/llms.txt 获取文档索引—通过在任何 URL 路径后添加 .md 可获取所有页面的 Markdown 版本。
Docs 菜单

GridFS

在本指南中,您可以了解如何使用GridFS在 MongoDB 中存储和检索大文件。 GridFS 规范描述了如何在存储过程中将文件分割为数据块,并在检索过程中重新组合这些数据块。GridFS 的 Rust 驱动程序实现托管文件存储的操作和组织。

Use GridFS if the size of your file exceeds the BSON document size limit of 16 MB. GridFS also helps you access files without loading the entire file into memory. For more detailed information about whether GridFS is suitable for your use case, see the GridFS page in the Server manual.

要了解有关 GridFS 的更多信息,请导航至本指南中的以下部分:

GridFS 在bucket中组织文件,而bucket是一组包含文件数据块和描述性信息的 MongoDB collection。存储桶包含以下collection,根据 GridFS 规范中定义的约定命名:

  • chunks,存储二进制文件数据块

  • files,存储文件元数据

当创建新的 GridFS 存储桶时,Rust 驱动程序会执行以下操作:

  • 创建chunks和files集合,以默认存储桶名称fs作为前缀,除非您指定其他名称

  • 在每个collection上创建索引,确保高效检索文件和相关元数据

You can create a reference to a GridFS bucket by following the steps in the Reference a GridFS Bucket section of this page. However, the driver does not create a new GridFS bucket and its indexes until the first write operation. For more information on GridFS indexes, see the GridFS Indexes page in the Server manual.

在 GridFS 存储桶中存储文件时,Rust 驱动程序会创建以下文档:

  • files 集合中的一个文档,存储唯一文件 ID、文件名和其他文件元数据

  • chunks collection中存储文件内容的一个或多个文档,驱动程序会将其分割成较小的部分

下图描述了 GridFS 在上传到存储桶时如何分割文件:

显示 GridFS 如何将文件上传到存储桶的图表

在检索文件时,GridFS 从指定存储桶上的 files 集合中获取元数据,并使用该信息通过 chunks 集合中的文档重建文件。您可以将文件读取到内存中,或者将其输出到流。

在 GridFS 存储桶中存储文件之前,请创建存储桶引用或获取对现有存储桶的引用。

以下示例对数据库实例调用gridfs_bucket()方法,该方法创建对新的或现有 GridFS 存储桶的引用:

let bucket = my_db.gridfs_bucket(None);

You can specify a custom bucket name and other options in a GridFsBucketOptions struct instance. 要开始构建GridFsBucketOptions实例,请调用GridFsBucketOptions::builder()方法。

注意

实例化选项

Rust 驱动程序实现了用于创建许多不同类型的 Builder 设计模式,包括GridFsBucketOptions 。 您可以使用builder()方法通过链接选项构建器方法来构造每种类型的实例。

下表描述了可用于设置GridFsBucketOptions实例字段的构建器方法:

方法
Possible Values
说明

bucket_name()

任何String值

指定存储桶名称,默认设置为fs

chunk_size_bytes()

任何u32值

指定用于将文件拆分为多个数据块的数据块大小,默认为 255 KB

write_concern()

WriteConcern::w,
WriteConcern::w_timeout,
WriteConcern::journal

指定存储桶的写关注,默认设置为数据库的写关注

read_concern()

ReadConcernLevel::Local, ReadConcernLevel::Majority , ReadConcernLevel::Linearizable , ReadConcernLevel::Available , ReadConcernLevel::Snapshot

指定存储桶的读关注,默认设置为数据库的读关注

selection_criteria()

SelectionCriteria::ReadPreference,
SelectionCriteria::Predicate

指定适合进行存储桶操作的服务器,默认设置为数据库的选择标准

以下示例在GridFsBucketOptions实例中指定选项,为写入操作配置自定义存储桶名称和五秒时间限制:

let wc = WriteConcern::builder().w_timeout(Duration::new(5, 0)).build();
let opts = GridFsBucketOptions::builder()
.bucket_name("my_bucket".to_string())
.write_concern(wc)
.build();
let bucket_with_opts = my_db.gridfs_bucket(opts);

您可以通过打开上传流并将文件写入该流来将文件上传到 GridFS 存储桶。 在存储桶实例上调用open_upload_stream()方法以打开流。 此方法返回一个实例的GridFsUploadStream,您可以向其中写入文件的内容。要将文件内容上传到GridFsUploadStream ,请调用write_all()方法并将文件字节作为参数传递。

提示

导入所需模块

GridFsUploadStream 结构体实现 futures_io::AsyncWrite 特征。要使用 AsyncWrite 写入方法,例如 write_all(),请使用以下 use 声明将 AsyncWriteExt 模块导入到应用程序文件中:

use futures_util::io::AsyncWriteExt;

以下示例使用上传流将名为"example.txt"的文件上传到 GridFS 存储桶:

let bucket = my_db.gridfs_bucket(None);
let file_bytes = fs::read("example.txt").await?;
let mut upload_stream = bucket.open_upload_stream("example", None);
upload_stream.write_all(&file_bytes[..]).await?;
println!("Document uploaded with ID: {}", upload_stream.id());
upload_stream.close().await?;

您可以通过打开下载流并从流中读取文件来从 GridFS 存储桶下载文件。 对存储桶实例调用open_download_stream()方法,指定所需文件的_id值作为参数。 此方法返回一个实例GridFsDownloadStream ,您可以从中访问该文件。 要从GridFsDownloadStream读取文件,请调用read_to_end()方法并将向量作为参数传递。

提示

导入所需模块

GridFsDownloadStream结构实现了futures_io::AsyncRead特征。 要使用AsyncRead读取方法,例如read_to_end() ,请使用以下使用声明将AsyncReadExt模块导入到您的应用程序文件中:

use futures_util::io::AsyncReadExt;

以下示例使用下载流从 GridFS 存储桶下载_id值为3289的文件:

let bucket = my_db.gridfs_bucket(None);
let id = ObjectId::from_str("3289").expect("Could not convert to ObjectId");
let mut buf = Vec::new();
let mut download_stream = bucket.open_download_stream(Bson::ObjectId(id)).await?;
let result = download_stream.read_to_end(&mut buf).await?;
println!("{:?}", result);

注意

GridFS 流媒体 API 无法加载部分数据块。当下载流需要从 MongoDB 拉取一个数据块时,它会将整个数据块拉取到内存中。255 KB 默认数据块大小通常足够,但您可以减小数据块大小以减少内存开销。

您可以检索有关 GridFS 存储桶的 files 集合中存储的文件的信息。每个文件都作为 FilesCollectionDocument 类型的实例存储,其中包括以下表示文件信息的字段:

  • _id:文件 ID

  • length:文件大小

  • chunk_size_bytes:文件的数据块大小

  • upload_date:文件的上传日期和时间

  • filename:文件的名称

  • metadata:存储用户指定元数据的文档

在 GridFS 存储桶实例上调用find()方法,从存储桶中检索文件。 该方法返回一个游标实例,您可以从该实例访问结果。

以下示例检索并打印 GridFS 存储桶中每个文件的长度:

let bucket = my_db.gridfs_bucket(None);
let filter = doc! {};
let mut cursor = bucket.find(filter, None).await?;
while let Some(result) = cursor.try_next().await? {
println!("File length: {}\n", result.length);
};

提示

要了解有关find()方法的更多信息,请参阅检索数据指南。 要了解有关从游标检索数据的更多信息,请参阅《使用游标访问数据》指南。

您可以通过在存储桶实例上调用rename()方法来更新存储桶中 GridFS 文件的名称。 将目标文件的_id值和新文件名作为参数传递给rename()方法。

注意

rename() 方法每次仅支持更新一个文件的名称。要重命名多个文件,请从存储桶中检索与文件名匹配的文件列表,从要重命名的文件中提取 _id 字段(Field),然后将每个值分别传递到 rename() 方法。

以下示例将包含_id值为3289的文件的filename字段更新为"new_file_name" :

let bucket = my_db.gridfs_bucket(None);
let id = ObjectId::from_str("3289").expect("Could not convert to ObjectId");
let new_name = "new_file_name";
bucket.rename(Bson::ObjectId(id), &new_name).await?;

您可以使用delete()方法从存储桶中删除文件。 要删除文件,请在存储桶实例上调用delete()并将文件的_id值作为参数传递。

注意

delete()方法一次只支持删除一个文件。 要删除多个文件,请从存储桶中检索文件,提取要删除的文件中的字段,然后将每个_id _id值分别调用给delete() 方法。

以下示例删除_id字段的值为3289的文件:

let bucket = my_db.gridfs_bucket(None);
let id = ObjectId::from_str("3289").expect("Could not convert to ObjectId");
bucket.delete(Bson::ObjectId(id)).await?;

您可以使用drop()方法删除存储桶,这会删除存储桶的files和chunkscollection。要删除存储桶,请对存储桶实例调用drop() 。

以下示例删除了一个 GridFS 存储桶:

let bucket = my_db.gridfs_bucket(None);
bucket.drop().await?;

要进一步了解本指南所提及的任何方法或类型,请参阅以下 API 文档: