MongoDB GridFS

什么是 GridFS?

MongoDB 的 GridFS 是用于存储和检索超过 16M 文档大小限制的文件的规范。GridFS 不会将文件存储在单个文档中,而是将文件分成多个部分或大块。并将每个大块存储为单独的文档。

GridFS 可以更好的存储大于 16M 的文件。

GridFS 会将大文件对象分割成多个小的 chunk(文件片段),一般为 256k/个。每个 chunk 将作为 MongoDB 的一个文档(document)被存储在 chunks 集合中。

GridFS 用两个集合来存储一个文件:fs.files 与 fs.chunks。

每个文件的实际内容被存在 chunks(二进制数据)中,和文件有关的 meta 数据(filename,content_type,还有用户自定义的属性)将会被存在 files 集合中。

GridFS 是如何存储文件的?

GridFS 使用两个集合来存储文件,一个集合存储文件块(fs.chunks),另一个集合存储文件元数据(fs.files)。当查询文件时,驱动程序将根据需要重新组装文件块。如下图:

MongoDB GridFS

注意:我们可以对 GridFS 存储的文件进行范围查询,也可以从文件的任意部分访问信息,比如跳到视频或音频文件的中间部分。如下:

(1)files 集合:File块,存储每个文件的元数据,一个文档代表 GridFS 中的一个文件。如下:

{
 " _id": <ObjectId>, #该文档的唯一标识符。该_id是你选择的原始文档中的数据类型。
 "length": <num>, # 文档的大小(以字节为单位)。
 "chunkSize":  <num>, # 每个块的大小(以字节为单位)。
 "uploadDate":  <时间戳>, # GridFS首次存储文档的日期。此值具有 Date类型。
 "md5": <哈希>,
 "filename": <字符串>, # 可选的。GridFS文件的可读名称。
 "contentType": <字符串>,
 "aliases":  <字符串数组>,
 "metadata":  <任何>, # 元数据字段,可以是任何数据类型,并且可以包含您要存储的任何其他信息。
                     # 如果希望向files 集合中的文档添加其他任意字段,请将其添加到元数据字段中的对象。
}

(2)chunks 集合:Chunk块,存储每个文件的内容,存放二进制块,如下:

集合中的每个文档代表一个单独的文件块,如下:

{
 "_id": <ObjectId>, # 块的唯一ObjectId
 "files_id": <ObjectId >, # 在_id“父”的文件,如在指定的files 集合。
 "n": <num>, # 块的序列号。GridFS从0开始对所有块进行编号。
 "data": <二进制>  # 块的有效载荷作为BSON Binary类型。
}

什么时候使用 GridFS?

(1)如果文件系统限制了目录中文件的数量,则可以使用 GridFS 来存储所需数量的文件。

(2)当您要访问大文件的部分信息而不必将整个文件加载到内存中时,可以使用 GridFS 来查看文件的某些部分,而无需将整个文件读入内存。

(3)当您想要使文件和元数据自动同步并跨多个系统和设施部署时,可以使用 GridFS。使用地理上分散的副本集时,MongoDB 可以自动将文件及其元数据分发到许多 mongod实例和设施。

注意:如果文件均小于 16 MB 的限制,请考虑将每个文件存储在单个文档中,而不要使用 GridFS 存储。

简单示例

上传文件

将 D:\mongo_demo.txt 文件上传到本地 Mongodb 服务的 files 数据库中,如:

D:\mongodb-win32-x86_64-windows-5.0.20\bin> mongofiles.exe -d files put D:\mongo_demo.txt
2023-09-21T12:40:33.279+0800    connected to: mongodb://localhost/
2023-09-21T12:40:33.358+0800    adding gridFile: D:\mongo_demo.txt

2023-09-21T12:40:34.230+0800    added gridFile: D:\mongo_demo.txt

上传成功后,查看 files 数据库信息,你会发现多出了 fs.chunks 和 fs.files 集合,它们的内容分别如下图:

MongoDB GridFS

MongoDB GridFS

通过上图可知,fs.files 集合中存储的是文件的基础信息,如文件名、大小、日期等信息。fs.chunks 集合存储的是文件的正文部分,总共使用了 176 个文档来存储该文件。

下载文件

(1)将根据文件名下载文件,将下载的文件存放到当前目录下的 tmp 目录下,名为 mongo_demo.txt。

D:\mongodb-win32-x86_64-windows-5.0.20\bin> mongofiles.exe -d files get D:\mongo_demo.txt --local .\tmp\mongo_demo.txt
2023-09-21T16:36:54.701+0800    connected to: mongodb://localhost/
2023-09-21T16:36:55.045+0800    finished writing to .\tmp\mongo_demo.txt

D:\mongodb-win32-x86_64-windows-5.0.20\bin>cd tmp

D:\mongodb-win32-x86_64-windows-5.0.20\bin\tmp>dir
驱动器 D 中的卷是 数据盘
卷的序列号是 10E3-09C5

D:\mongodb-win32-x86_64-windows-5.0.20\bin\tmp 的目录

2023/09/21  16:36    <DIR>          .
2023/09/21  16:36    <DIR>          ..
2023/09/21  16:36        45,888,890 mongo_demo.txt
              1 个文件     45,888,890 字节
              2 个目录 253,072,306,176 可用字节

(2)根据文件的 objectId 下载文件,下载的文件存放到当前目录下的 tmp 目录下,名为 mongo_demo.txt。

D:\mongodb-win32-x86_64-windows-5.0.20\bin> mongofiles.exe get_id 'ObjectId("650bc941e9d07e82851d1e9d")' --local .\tmp\mongo_demo.txt
2023-09-21T17:00:51.015+0800    connected to: mongodb://localhost/
2023-09-21T17:00:51.065+0800    Failed: no such file with _id: 'ObjectId(650bc941e9d07e82851d1e9d)'

查看文件

(1)查看所有文件信息,例如:查询 files 数据库中所有的文件信息

D:\mongodb-win32-x86_64-windows-5.0.20\bin> mongofiles.exe -d files list
2023-09-21T17:02:49.422+0800    connected to: mongodb://localhost/
D:\mongo_demo.txt       45888890

(2)查看指定前缀的文件信息,例如:查询 files 数据库中文件名前缀为 “D:\mongo” 的文件信息

D:\mongodb-win32-x86_64-windows-5.0.20\bin> mongofiles.exe -d files list D:\mongo
2023-09-21T17:05:51.394+0800    connected to: mongodb://localhost/
D:\mongo_demo.txt       45888890

D:\mongodb-win32-x86_64-windows-5.0.20\bin> mongofiles.exe -d files list D:\mongo_demo
2023-09-21T17:06:10.255+0800    connected to: mongodb://localhost/
D:\mongo_demo.txt       45888890

(3)从指定的服务器上查看文件信息,例如:

D:\mongodb-win32-x86_64-windows-5.0.20\bin> mongofiles.exe --host 127.0.0.1 --port 27017 -d files list
2023-09-21T17:11:11.906+0800    connected to: mongodb://127.0.0.1:27017/
D:\mongo_demo.txt       45888890

搜索文件

(1)根据文件名搜索指定文件,例如:在 files 数据库中搜索名为 mongo_demo.txt 的文件信息。

D:\mongodb-win32-x86_64-windows-5.0.20\bin> mongofiles.exe -d files search mongo_demo.txt
2023-09-21T17:16:11.079+0800    connected to: mongodb://localhost/
D:\mongo_demo.txt       45888890

删除文件

(1)根据文件名删除

D:\mongodb-win32-x86_64-windows-5.0.20\bin> mongofiles.exe -d files delete D:\mongo_demo.txt
2023-09-21T17:18:46.783+0800    connected to: mongodb://localhost/
2023-09-21T17:18:46.882+0800    successfully deleted all instances of 'D:\mongo_demo.txt' from GridFS

(2)根据 objectid 删除

mongofiles.exe -d files delete_id 'ObjectId("650c0ad578f7d7346999e7ce")'

mongofiles 命令

mongofiles 是 MongoDB 的一个命令行工具,用于在 GridFS 中存储、检索和管理文件。语法格式:

mongofiles <选项> <命令> <文件名>

详细说明:

  • 选项:您可以使用这些选项中的一个或多个来控制 mongofiles 的行为,更多选项请参考 mongofiles。

  • 文件名:可以是本地文件系统上的文件名或 GridFS 对象。

  • 命令:让 mongofiles 命令去做具体事情的指令,命令包含:

    • list <prefix>  列出 GridFS 中存储的文件。在 list(例如 <prefix>)之后指定的字符(可选)将返回的项目列表限制为以该字符串开头的文件。

    • search <string>  列出 GridFS 中存储的文件名称或任何部分与指定的 <string> 匹配的文件。

    • put <filename>  将指定的文件从本地文件系统复制到 GridFS 存储中。注意,<filename> 是指对象在 GridFS 中将具有的名称,并且 mongofiles 认为本地文件系统上的文件名字也是该名称。如果本地文件名不同, --local 选项指定。

    • get <filename>  将指定的文件从 GridFS 存储中复制到本地文件系统。注意,<filename> 是指对象在 GridFS 中将具有的名称。mongofiles 使用 <filename> 将 GridFS 中的文件写入本地文件系统。如果要为本地文件系统上的文件选择其他位置或重命名,请使用 --local 选项。

    • get_id "<_id>"  3.2.0 版中的新功能。将指定的文件 <_id> 从 GridFS 存储中复制到本地文件系统。这里 <_id> 指的是 GridFS 中对象 id :

      • 从 MongoDB 4.2 开始,get_id 可以接受的 ObjectId 值或非 ObjectId 值 <_id>。

      • 在 MongoDB 4.0 和更早版本中,get_id 仅接受 <ObjectId> 值。

    • delete <filename>  从 GridFS 存储中删除指定的文件。

    • delete_id "<_id>"  3.2.0 版中的新功能。根据 <_id> 从 GridFS 存储中删除指定的文件:

      • 从 MongoDB 4.2 开始,delete_id 可以接受的 ObjectId 值或非 ObjectId 值 <_id>。

      • 在 MongoDB 4.0 和更早版本中,delete_id 仅接受 <ObjectId> 值。

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号