Docs 菜单
Docs 主页
/ / /
Scala
/

使用GridFS存储大文件

在此页面上

  • Overview
  • GridFS 的工作原理
  • 创建 GridFS 存储桶
  • 上传文件
  • 检索文件信息
  • 下载文件
  • 重命名文件
  • 删除文件
  • API 文档

在本指南中,您可以学习;了解如何使用GridFS在MongoDB中存储和检索大文件。 GridFS规范描述了如何在存储文件时将文件分割为数据段,并在检索文件时重新组合文件。 GridFS的Scala驱动程序实施是一个用于管理文件存储的操作和组织的抽象。

如果文件大小超过16 MB 的BSON文档大小限制,请使用GridFS 。 有关GridFS是否适合您的使用案例的更多详细信息,请参阅MongoDB Server手册中的 GridFS

以下部分描述了 GridFS 操作以及如何执行这些操作。

GridFS 在存储桶中组织文件,存储桶是一组包含文件数据段及其描述信息的MongoDB 集合。存储桶包含以下集合,使用 GridFS 规范中定义的约定命名:

  • chunks 集合存储二进制文件数据段。

  • files 集合存储文件元数据。

当您创建新的GridFS存储桶时,驾驶员会创建fs.chunksfs.files 集合,除非您在GridFSBucket() 构造函数中指定不同的名称。该驾驶员还会在每个集合上创建一个索引,以确保有效检索文件和相关元数据。如果GridFS存储桶不存在,则驾驶员仅在执行第一次写入操作时才会创建该存储桶。仅当索引不存在且存储桶为空时,驾驶员才会创建索引。有关GridFS索引的更多信息,请参阅MongoDB Server手册中的GridFS索引。

使用 GridFS 存储文件时,驱动程序会将文件拆分成较小的数据块,每个数据块由 chunks 集合中的单独文档表示。它还在 files 集合中创建文档,其中包含文件 ID、文件名和其他文件元数据。您可以从内存或数据流上传文件。请参阅下图,了解 GridFS 在上传到存储桶时如何拆分文件。

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

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

要从 GridFS 存储或检索文件,请调用GridFSBucket()构造函数并传入MongoDatabase实例,以创建 GridFS 存储桶。 您可以使用GridFSBucket实例对存储桶中的文件调用读取和写入操作。

val bucket = GridFSBucket(database)

要使用默认名称 fs 以外的默认定义名称创建或引用存储桶,请将存储桶名称作为第二个参数传递给 GridFSBucket() 构造函数,如以下示例所示:

val filesBucket = GridFSBucket(database, "files")

GridFSBucket.uploadFromObservable()方法读取Observable[ByteBuffer]的内容并将其保存到GridFSBucket实例中。

您可以使用GridFSUploadOptions类型来配置数据段大小或包含其他元数据。

以下示例将 Observable[ByteBuffer] 的内容上传到 GridFSBucket

// Get the input stream
val observableToUploadFrom = Observable(
Seq(ByteBuffer.wrap("MongoDB Tutorial".getBytes(StandardCharsets.UTF_8)))
)
// Create some custom options
val options = new GridFSUploadOptions()
.chunkSizeBytes(358400)
.metadata(Document("type" -> "presentation"))
// Upload the file
val fileIdObservable = filesBucket.uploadFromObservable("mongodb-tutorial", observableToUploadFrom, options)
val fileId = Await.result(fileIdObservable.toFuture(), Duration(10, TimeUnit.SECONDS))
println(s"File uploaded with id: ${fileId.toHexString}")

在本部分中,您可以了解如何检索存储在 GridFS 存储桶的 files 集合的文件元数据。元数据包含所引用文件的相关信息,包括:

  • 文件的 _id

  • 文件的名称

  • 文件的长度/大小

  • 上传日期和时间

  • 您可以在其中存储任何其他信息的 metadata 文档

要学习;了解有关可从files 集合检索的字段的更多信息,请参阅MongoDB Server手册中的GridFS文件集合文档。

要从GridFS存储桶检索文件,请对 GridFSBucket实例调用 find() 方法。以下代码示例从GridFS存储桶中的所有文件中检索并打印文件元数据:

val filesObservable = filesBucket.find()
val results = Await.result(filesObservable.toFuture(), Duration(10, TimeUnit.SECONDS))
results.foreach(file => println(s" - ${file.getFilename}"))

要学习;了解有关查询MongoDB 的更多信息,请参阅 检索数据。

downloadToObservable()方法返回一个Observable[ByteBuffer] ,用于从MongoDB读取内容。

要通过文件_id下载文件,请将_id传递给该方法。 以下示例通过文件_id下载文件:

val downloadObservable = filesBucket.downloadToObservable("<example file ID>")
val downloadById = Await.result(downloadObservable.toFuture(), Duration(10, TimeUnit.SECONDS))

如果您不知道文件的 _id,但知道文件名,则可以将文件名传递给 downloadToObservable() 方法。以下示例下载名为 mongodb-tutorial 的文件:

val downloadObservable = filesBucket.downloadToObservable("mongodb-tutorial")
val downloadById = Await.result(downloadObservable.toFuture(), Duration(10, TimeUnit.SECONDS))

注意

如果多个文档具有相同的 filename 值, GridFS将获取具有给定名称(由 uploadDate字段确定)的最新文件。

使用 rename() 方法更新存储桶中 GridFS 文件的名称。您必须用文件的 _id 字段而不是文件名来指定要重命名的文件。

如下示例将一个文件重命名为 mongodbTutorial

val renameObservable = filesBucket.rename("<example file ID>", "mongodbTutorial")
Await.result(renameObservable.toFuture(), Duration(10, TimeUnit.SECONDS))

注意

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

使用 delete() 方法从存储桶中删除文件的集合文档和关联的数据段。您必须用文件的 _id字段而不是文件名来指定文件。

以下示例通过 _id 删除文件:

val deleteObservable = filesBucket.delete("<example file ID>")
Await.result(deleteObservable.toFuture(), Duration(10, TimeUnit.SECONDS))

注意

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

要学习;了解有关使用GridFS存储和检索大文件的更多信息,请参阅以下API文档:

后退

事务