MongoDB(八) - MongoDB GridFS介绍及使用Python操作GridFS

文章目录

  • 前言
  • 一、GridFS概述
    • [1. GridFS介绍](#1. GridFS介绍)
    • [2. GridFS应用场景](#2. GridFS应用场景)
  • 二、GridFS存储结构
  • [三、使用Shell操作MongoDB GridFS(MongoDB 5 中已弃用)](#三、使用Shell操作MongoDB GridFS(MongoDB 5 中已弃用))
    • [1. mongofiles工具的语法及说明](#1. mongofiles工具的语法及说明)
      • [1.1 基本语法结构](#1.1 基本语法结构)
      • [1.2 常用选项说明](#1.2 常用选项说明)
      • [1.3 常用命令介绍](#1.3 常用命令介绍)
  • [四、使用 Python 操作 MongoDB GridFS](#四、使用 Python 操作 MongoDB GridFS)
    • [1. 安装依赖库](#1. 安装依赖库)
    • [2. 连接 MongoDB 数据库](#2. 连接 MongoDB 数据库)
    • [3. 使用 GridFS 存储文件](#3. 使用 GridFS 存储文件)
      • [3.1 上传文件](#3.1 上传文件)
      • [3.2 列出所有文件](#3.2 列出所有文件)
      • [3.3 下载文件](#3.3 下载文件)
      • [3.4 删除文件](#3.4 删除文件)
    • [4. 完整代码](#4. 完整代码)

前言

本文将系统介绍 GridFS 的核心概念、存储结构及操作方法,涵盖MongoDB Shell 工具和Python 编程接口的实战案例。通过理论与代码结合的方式,帮助读者快速掌握 GridFS 在实际项目中的应用,理解其在可扩展性、可靠性和检索效率上的优势,为构建高性能文件存储系统提供技术参考。


一、GridFS概述

1. GridFS介绍

GridFS是一种用于存储和检索大型二进制文件(如图片、视频、音频等)的规范,它基于MongoDB数据库构建。通常情况下,MongoDB对单个文档的大小限制为16MB,而GridFS则允许存储远超这个大小限制的文件。它通过将文件分割成多个较小的部分(通常是255KB大小的块),然后每个块作为一个单独的文档存储在集合中来实现这一点。这种方式不仅绕过了单文档大小的限制,而且也使得可以高效地访问文件的特定部分,而无需加载整个文件。

2. GridFS应用场景

GridFS特别适用于需要在MongoDB中存储和管理大型文件的场景,尤其是在传统文件系统可能遇到挑战的情况下。以下是几个典型的GridFS应用场景:

  1. 多媒体内容存储:对于图片、音频、视频等多媒体文件,特别是那些大小超过MongoDB单文档限制(16MB)的文件,GridFS提供了一个有效的解决方案。例如,在线教育平台可以使用GridFS来存储课程视频。

  2. 备份与归档:GridFS能够用于存储数据库备份或重要数据的归档版本。由于MongoDB本身支持复制和分片功能,这使得GridFS成为一种可靠的数据持久化选择。

  3. 分布式文件存储:当需要跨多个服务器分布文件存储时,GridFS结合MongoDB的分片功能可以轻松实现这一目标。这对于构建云存储服务非常有用,因为它允许无缝扩展存储容量,并提供了良好的容错能力。

  4. 大文件处理:在某些应用中,如医疗影像存储、高清地图数据等需要处理超大文件的场合,GridFS可以方便地管理和检索这些文件,同时利用MongoDB的查询能力进行快速定位。

  5. 实时数据分析:虽然GridFS主要用于存储大型二进制文件,但其元数据存储特性也使其适合于需要对文件元数据执行复杂查询的应用场景。例如,媒体库可以根据文件类型、上传时间等元数据迅速过滤和查找特定文件。

总之,GridFS通过将文件分割成小块并以MongoDB文档的形式存储,解决了传统文件系统面临的许多问题,特别是在可扩展性、冗余性和高效检索方面提供了新的解决方案。然而,值得注意的是,对于小于16MB的小型文件,直接使用MongoDB的普通文档存储会更加高效。


二、GridFS存储结构

GridFS使用两个集合来存储文件数据:fs.filesfs.chunks

  • fs.files: 这个集合存储了文件的元数据。每个文件对应于一个文档,该文档包含了文件的基本信息,比如文件名、文件大小、上传时间戳、内容类型等。这些元数据有助于快速查找和管理文件。

  • fs.chunks : 这个集合存储了文件的实际内容。文件被分成多个块,每个块作为单独的文档存储在这个集合中。每个块文档包含了一个索引字段(表示该块在整个文件中的位置)、实际的数据块以及指向fs.files集合中相应文件的引用(即文件的唯一标识符)。

当需要检索一个文件时,首先查询fs.files集合获取文件的元数据,然后根据元数据中提供的信息从fs.chunks集合中按顺序读取所有相关的块,并将这些块重新组装成原始文件。

这种设计让GridFS能够灵活且高效地处理大规模文件存储需求,同时也利用了MongoDB的分片和复制功能,提供了良好的扩展性和可靠性。


三、使用Shell操作MongoDB GridFS(MongoDB 5 中已弃用)

使用MongoDB Shell操作GridFS涉及几个基本命令和语法,主要通过mongofiles工具或直接在MongoDB Shell中使用GridFS API来实现文件的上传、下载、删除等操作。

1. mongofiles工具的语法及说明

mongofiles 是 MongoDB 提供的一个命令行工具,专门用于通过 Shell 操作 GridFS 中的文件。它可以直接对 GridFS 集合(默认为 fs.filesfs.chunks)进行上传、下载、删除、列出等操作。

1.1 基本语法结构

bash 复制代码
mongofiles [options] <command> [filename]
  • [options]:各种可选参数,如数据库名、连接信息、用户名密码等。
  • <command>:要执行的操作,如 putgetlistdelete 等。
  • [filename]:指定操作的文件名(某些命令不需要)。

1.2 常用选项说明

选项 说明 示例
--help 查看所有选项和命令的用法帮助信息 mongofiles --help
--host 指定 MongoDB 主机地址(可带端口) --host localhost:27017
--port 指定 MongoDB 端口号(如果 --host 中没有指定) --port 27018
-u, --username 登录数据库使用的用户名 -u admin
-p, --password 登录数据库使用的密码 -p password123
-d, --db 指定要操作的数据库名称(GridFS 文件存储在该数据库中) -d myfilesdb
-l, --local 指定本地文件路径,用于 putget 操作 --local localname.txt
--authenticationDatabase 指定认证数据库(当用户账户不在目标数据库时需要) --authenticationDatabase admin
-r, --replace 替换已存在的同名文件。上传时如果文件名重复,默认不会替换,加上此参数则会覆盖旧文件 mongofiles -d gridfsdb -r put test.jpg
-c, --collection 指定集合前缀(默认是 fs),实际创建的集合为 <prefix>.files<prefix>.chunks -c photos 表示使用 photos.filesphotos.chunks

1.3 常用命令介绍

命令 用途 示例
list 列出 GridFS 中所有文件(显示文件名及大小) mongofiles -d mydb list
search 根据文件名模糊搜索匹配的文件(支持通配符) mongofiles -d mydb search image
put 将本地文件上传到 GridFS mongofiles -d mydb put /path/to/file.txt
get 根据文件名从 GridFS 下载文件 mongofiles -d mydb get file.txt --out /path/to/save.txt
delete 删除指定文件名的文件 mongofiles -d mydb delete file.txt
get_id 根据文件的 _id 下载文件(精确下载) mongofiles -d mydb get_id ObjectId("5f5fc6c59528df3b704b2e44") --out output.txt
delete_id 根据文件的 _id 删除文件(精确删除) mongofiles -d mydb delete_id ObjectId("5f5fc6c59528df3b704b2e44")

四、使用 Python 操作 MongoDB GridFS

1. 安装依赖库

在开始之前,请确保你已经安装了 pymongogridfs 模块(gridfspymongo 的一部分):

bash 复制代码
pip install pymongo

2. 连接 MongoDB 数据库

首先需要连接到 MongoDB 实例并选择一个数据库。GridFS 文件将存储在该数据库中。

python 复制代码
from pymongo import MongoClient

# 连接到本地 MongoDB 实例
client = MongoClient('mongodb://localhost:27017/')

# 选择数据库(如果不存在会自动创建)
db = client['db_movie']

3. 使用 GridFS 存储文件

pymongo 提供了 gridfs.GridFS 类来操作 GridFS 文件系统。

3.1 上传文件

put()方法可以将本地文件上传到 GridFS。

方法签名:

python 复制代码
fs.put(data, filename=None, content_type=None, chunk_size=256*1024, metadata=None)

参数说明:

参数名 类型 说明
data file-like object 要上传的文件数据(通常是打开的二进制文件对象)
filename str 存储在 GridFS 中的文件名
content_type str 可选,指定 MIME 类型(如 'image/jpeg'
chunk_size int 分块大小(字节),默认 256KB
metadata dict 可选,附加的元数据信息

示例:

把文件movies.csv上传到GridFS。

python 复制代码
# 初始化 GridFS
fs = gridfs.GridFS(database=db, collection='fs')

# 上传文件
with open(f"movies.csv", "rb") as f:
    result_id = fs.put(f, filename="movies.csv", metadata={"author": "Alice"})
    print("文件上传成功:"+result_id)

3.2 列出所有文件

python 复制代码
# 列出所有文件的文件名(如果多个文件的文件名相同,只列出一个文件名)
print("GridFS中的文件:")
file_list = fs.list()
print(file_list)
# 列出所有文件的元数据信息
print("GridFS中所有文件的元数据信息:")
file_list2 = fs.find()
for file in file_list2:
    print(f"ID:{file._id}),文件名:{file.filename},元数据:{file.metadata},文件大小:{file.chunk_size},长度:{file.length},上传时间:{str(file.upload_date)}")

3.3 下载文件

get() / find_one()方法用于从 GridFS 中根据文件名或 _id 获取文件内容。

方法签名:

python 复制代码
file = fs.get(file_id)  # 返回 GridOut 对象
python 复制代码
file = fs.find_one(filter)  # 返回 GridOut 对象

参数说明:

参数名 类型 说明
file_id ObjectId 或 str 文件的唯一标识符,可以是 ObjectId 类型或其字符串表示
filter dict 查询条件,如 {"filename": "example.txt"}

示例:

python 复制代码
# 通过匹配文件名下载文件
file_data = fs.find_one({"filename": "movies.csv"})
with open("downloaded_movies.csv", "wb") as f:
    f.write(file_data.read())
    print("文件下载成功")

# 通过文件id下载文件
file_data = fs.get(file_id)
with open("downloaded_movies2.csv", "wb") as f:
    f.write(file_data.read())
    print("文件下载成功")

3.4 删除文件

delete()方法用于删除指定 _id 的文件(注意:GridFS 不支持直接通过文件名删除)。

方法签名:

python 复制代码
fs.delete(file_id)

示例:

python 复制代码
# 删除文件
file_id = fs.find_one({"filename": "movies.csv"})._id
fs.delete(file_id)
print("文件删除成功")

4. 完整代码

python 复制代码
import gridfs
from pymongo import MongoClient

# 连接数据库
client = MongoClient('mongodb://localhost:27017/')
db = client['db_movie']

# 初始化 GridFS
fs = gridfs.GridFS(database=db, collection='fs')

# 上传文件
with open(f"D:\\bigdata\\mongodb-python-demo\\movies.csv", "rb") as f:
    file_id = fs.put(f, filename="movies.csv", metadata={"author": "Alice"})
    print("文件上传成功:" + str(file_id))

# 列出所有文件的文件名(如果多个文件的文件名相同,只列出一个文件名)
print("GridFS中的文件:")
file_list = fs.list()
print(file_list)
# 列出所有文件的元数据信息
print("GridFS中所有文件的元数据信息:")
file_list2 = fs.find()
for file in file_list2:
    print(
        f"ID:{file._id}),文件名:{file.filename},元数据:{file.metadata},文件大小:{file.chunk_size},长度:{file.length},上传时间:{str(file.upload_date)}")

# 通过匹配文件名下载文件
file_data = fs.find_one({"filename": "movies.csv"})
with open("downloaded_movies.csv", "wb") as f:
    f.write(file_data.read())
    print("文件下载成功")

# 通过文件id下载文件
file_data = fs.get(file_id)
with open("downloaded_movies2.csv", "wb") as f:
    f.write(file_data.read())
    print("文件下载成功")

# 删除文件
file_id = fs.find_one({"filename": "movies.csv"})._id
fs.delete(file_id)
print("文件删除成功")
相关推荐
noravinsc2 分钟前
django 获取当前时间 格式 YYYY-MM-DD HH:Mm:ss
python·django·sqlite
谢李由2023032208115 分钟前
网络爬虫学习心得
爬虫·python
爱意随风起风止意难平16 分钟前
AIGC 基础篇 Python基础 05 元组,集合与字典
开发语言·python·aigc
栗子不爱栗子21 分钟前
从理解AI到驾驭文字:一位技术爱好者的写作工具探索手记
python·学习·ai
wh_xia_jun1 小时前
mybatis xml 配置中,jdbcType=VARCHAR 的作用
数据库·oracle·tomcat
程序猿小D2 小时前
第24节 Node.js 连接 MongoDB
数据库·mongodb·npm·node.js·编辑器·vim·express
飞翔的佩奇2 小时前
【完整源码+数据集+部署教程】石材实例分割系统源码和数据集:改进yolo11-CA-HSFPN
python·yolo·计算机视觉·毕业设计·数据集·yolo11·石材实例分割系统
鹏说大数据2 小时前
使用Conda管理服务器多版本Python环境的完整指南
服务器·python·conda
武汉格发Gofartlic3 小时前
FEMFAT许可使用数据分析工具介绍
python·信息可视化·数据分析
love530love3 小时前
【笔记】NVIDIA AI Workbench 中安装 cuDNN 9.10.2
linux·人工智能·windows·笔记·python·深度学习