GridFS
GridFS 是用于存储和检索超过16 MB BSON 文档大小限制的文件的规范。 GridFS 不是将大文件存储在单个文档中,而是将文件划分为多个部分或数据段,并将每个数据段存储为单独的文档。
当您在 GridFS 存储中查询文件时,驱动程序会根据需要重新组合数据段。
本指南中的代码示例来自驾驶员源代码GitHub存储库中的 GridFSTour.scala 文件。
先决条件
您必须在程序中包含以下 import 语句才能运行本指南中的代码示例:
import java.nio.ByteBuffer import java.nio.charset.StandardCharsets import org.mongodb.scala._ import org.mongodb.scala.bson.BsonObjectId import org.mongodb.scala.gridfs._ import org.mongodb.scala.model.Filters import tour.Helpers._ import scala.util.Success
注意
本指南使用 Observable
隐式,如快速入门入门知识中所述。
连接到 MongoDB 部署
首先,连接到 MongoDB 部署并声明和定义一个MongoDatabase
实例。
以下代码连接到在端口27017
上的localhost
上运行的独立 MongoDB 部署:
val mongoClient: MongoClient = MongoClient()
要了解有关连接到 MongoDB 部署的更多信息,请参阅连接到 MongoDB指南。
创建 GridFS 存储桶
GridFS 将文件存储在两个集合中:
chunks
:存储文件数据段files
:存储文件元数据
这两个集合位于同一存储桶中,并且集合名称以存储桶名称为前缀。
驱动程序提供了GridFSBucket()
方法来创建GridFSBucket
实例:
val myDatabase = mongoClient.getDatabase("mydb") // Create a gridFSBucket using the default bucket name "fs" val gridFSBucket = GridFSBucket(myDatabase)
您可以将存储桶名称传递给GridFSBucket()
方法:
// Create a gridFSBucket with a custom bucket name "files" val gridFSFilesBucket = GridFSBucket(myDatabase, "files")
注意
当您将数据上传到 GridFS 存储桶时,GridFS 会自动在files
和chunks
集合上创建索引。
上传到 GridFS
GridFSBucket.uploadFromObservable()
方法读取Observable[ByteBuffer]
的内容并将其保存到GridFSBucket
实例中。
您可以使用GridFSUploadOptions
类型来配置数据段大小或包含其他元数据。
以下示例将Observable[ByteBuffer]
的内容上传到GridFSBucket
:
// Get the input stream val observableToUploadFrom: Observable[ByteBuffer] = Observable( Seq(ByteBuffer.wrap("MongoDB Tutorial".getBytes(StandardCharsets.UTF_8))) ) // Create some custom options val options: GridFSUploadOptions = new GridFSUploadOptions() .chunkSizeBytes(358400) .metadata(Document("type" -> "presentation")) val fileId: BsonObjectId = gridFSBucket .uploadFromObservable("mongodb-tutorial", observableToUploadFrom, options) .headResult()
查找存储在 GridFS 中的文件
要查找存储在GridFSBucket
中的文件,请使用find()
方法。
以下示例打印出存储的每个文件的文件名:
gridFSBucket.find().results().foreach(file => println(s" - ${file.getFilename}"))
您还可以提供自定义筛选器来限制返回的结果。 以下示例打印用户定义的元数据文档中contentType
值为image/png
值的所有文件的文件名:
gridFSBucket .find(Filters.equal("metadata.contentType", "image/png")) .results() .foreach(file => println(s" > ${file.getFilename}"))
从 GridFS 下载
downloadToObservable()
方法返回一个Observable[ByteBuffer]
,用于从MongoDB读取内容。
要通过文件_id
下载文件,请将_id
传递给该方法。 以下示例通过文件_id
下载文件:
val downloadById = gridFSBucket.downloadToObservable(fileId).results()
如果您不知道文件的_id
,但知道文件名,则可以将文件名传递给downloadToObservable()
方法。 默认情况下,它将下载该文件的最新版本。 使用GridFSDownloadOptions
类配置要下载的版本。
以下示例下载名为mongodb-tutorial
的文件的原始版本:
val downloadOptions: GridFSDownloadOptions = new GridFSDownloadOptions().revision(0) val downloadByName = gridFSBucket.downloadToObservable("mongodb-tutorial", downloadOptions).results()
重命名文件
如果需要重命名文件,请使用rename()
方法。
如下示例将一个文件重命名为 mongodbTutorial
:
val fileId: ObjectId = ... // ObjectId of a file uploaded to GridFS gridFSBucket.rename(fileId, "mongodbTutorial").printResults()
注意
rename()
方法需要ObjectId
而不是filename
,以确保重命名正确的文件。
要重命名同一文件名的多个修订版本,请先检索文件的完整列表。 然后,对于应重命名的每个文件,使用相应的 运行rename()
_id
。
删除文件
要从GridFSBucket
中删除文件,请使用delete()
方法。
以下示例从GridFSBucket
中删除一个文件:
val fileId: ObjectId = ... //ObjectId of a file uploaded to GridFS gridFSBucket.delete(fileId).printResults()