GridFS

GridFS

前言:

mongo对document有限制16M大小,如果插入超过此限制的数据则会报错。为了解决此问题,我们可以使用mongo的另一个特性GridFS来存储超大文件(文本文件,视频,音频等)

说明:

GridFS的使用机制就是将大文件拆分成小数据块chunk块,有序存放到mongo数据集合当中,以文档document的形式存在,这样的数据块我们称之为chunk;
chunk块的单位大小为255K,文件的最后一个chunk块除外,因为最后一个不一定正好是255Kb;

什么时候用GridFS

在MongoDB里,使用GridFS去存储超过16M的文件;
如下情况下将大文件存放在mongo中比在OS层面更有效:

如果系统对目录下的文件数量有限制,那么你可以考虑使用GridFS;
如果你想要访问大文件的部分信息,并且不想把整个文件都加载到内存中,则可以考虑使用GridFS;

如何存储:

GridFS使用两个集合来存储超大文件—- fs.files , fs.chunks:
- fs.files: 存放超大文件的元数据(medata),用来描述文件的大小,上传时间,文件名,md5校验码等等信息;
- fs.chunks: 存放超大的chunk块的二进制数据
fs.files集合结构:

{
    "_id" : ObjectId("598d3f5693e6c2353332c68b"),          ---文件id
    "chunkSize" : 261120,        ---chunk块的单位大小,一般情况下是255K
    "uploadDate" : ISODate("2017-08-11T05:23:34.362Z"),   ---此大文件的第一次上传时间
    "length" : 0,                                       ---文件大小
    "md5" : "d41d8cd98f00b204e9800998ecf8427e",         ---文件校验码
    "filename" : "testfile2"                            ---文件名
}

: 此集合中其实还保留了三个可选字段,contentType, aliases, metadata, 当然应用也可以创建额外的任意字段供业务需要;
fs.chunks集合结构:

{
    "_id" : ObjectId("598d3fd593e6c238c21e693d"),          ---主键id
    "files_id" : ObjectId("598d3fd593e6c238c21e693c"),      ---文件id,对应fs.files中的id,类似于外键
    "n" : 0,         ---chunk序列号,一个大文件有很多的chunk,序列从0开始
 "data" : BinData(0,"VGhpcyBpcyBhIHRlc3QgZmlsZSBmcm9tIEpvaG5ueQo=") 
                         ---chunk块对应的二进制数据
}

索引:

默认情况下,在第一次使用GridFS特性插入文件到mongo实例时,会自动在上述两个集合中分别创建一个索引(_id索引除外),如下:
注:如果索引不存在,还需自行创建

rs1:PRIMARY> db.fs.files.getIndexes()
[
    {
        "v" : 1,
        "key" : {
            "filename" : 1,
            "uploadDate" : 1
        },
        "name" : "filename_1_uploadDate_1",
        "ns" : "Johnny.fs.files"
    }
]
rs1:PRIMARY> db.fs.chunks.getIndexes()
[
    {
        "v" : 1,
        "unique" : true,
        "key" : {
            "files_id" : 1,
            "n" : 1
        },
        "name" : "files_id_1_n_1",
        "ns" : "Johnny.fs.chunks"
    }
]

如何使用GridFS

两种方法:驱动调用,命令行工具mongofiles
①驱动调用:
基本mongo支持的驱动都提供调用方法,在此就不多赘述了,具体如何使用还请参阅各自驱动文档
② 命令行工具:
mongofiles格式

mongofiles <options> <commands> <filename>

options:主要就是连接mongo实例的一些参数值,比如IP,端口,用户密码等等;
commands:mongfile的一些操作处理命令,比如写文件,读文件,查看文件列表等等;
filename:待操作的文件名称,或者GridFS中文件对象名(fs.files集合中的filename字段值);

权限:
如果mongo实例开启了auth认证服务,则在执行mongofile命令需要给予用户readWrite权限即可;
详细参数:
options其实没什么可说的,基本上就是一些连接参数;
filename也没什么讲的,就是文件对象名称,如果你要get文件,则必须使用的是fs.files集合中filename字段的值(如果有update过,则使用最近更新过的名称)

commands:
这个需要好好说说
list: 列出GridFS存储的所有文件名,以及对应的大小
search:搜索文件名包含某些字符串的文件,并列出, search “test”
put: 将文件写入GridFS存储中 put “testfile”
get: 从GridFS中提取文件到当前路径下,如果想要更改存放目录,则可以在options中使用–local 参数指定,get “testfile”
get_id: 根据GridFS中文件对应的file_id提取文件到当前路径下,3.2以后的新功能,get_id ‘ObjectId(“598d3fd593e6c238c21e693c”)’
delete: 从GridFS中删除指定文件,delete “testfile”
delete_id: 根据file_id删除指定文件, delete_id ‘ObjectId(“598d3fd593e6c238c21e693c”)’
例子:

mongofiles --host 10.25.161.14:27027 -uAdmin -padmin123 -d Johnny --authenticationDatabase admin put testfile.pdf
参数说明:
      --host, --port, -u, -p, --authenticationDatabase都与其他mongo命令参数一致的用法,不再赘述
      put: 就是上述讲过的commands命令
      testfile:对应你想要存储到数据库的超大文件名

上述例子就是将testfile.pdf图片存放到数据库中

### 使用 Python 和 MongoDBGridFS GridFS 是一种用于存储和检索超过 BSON 文档大小限制(16MB)的文件的标准方式。它将大文件拆分为多个较小的部分并将其作为单独的数据块存储在 `fs.chunks` 集合中,同时元数据则保存在 `fs.files` 中。 以下是使用 Python 和 PyMongo 库操作 GridFS 的基本方法: #### 安装依赖库 要使用 GridFS,需先安装 pymongo 库: ```bash pip install pymongo ``` #### 连接到 MongoDB 并初始化 GridFS 通过 PyMongo 提供的 `gridfs.GridFS` 类可以轻松访问 GridFS 功能。 ```python from pymongo import MongoClient import gridfs # 创建 MongoDB 客户端实例 client = MongoClient('mongodb://localhost:27017/') db = client['mydatabase'] # 替换为实际使用的数据库名称 # 初始化 GridFS 实例 fs = gridfs.GridFS(db) ``` #### 存储文件到 GridFS 可以通过二进制流的方式上传任意类型的文件至 GridFS。 ```python with open('/path/to/file', 'rb') as f: file_id = fs.put(f, filename="example_file", content_type="text/plain") # 添加自定义元数据 print(file_id) # 返回 ObjectId 表示成功插入 ``` #### 获取文件从 GridFS 可以根据文件名或其他条件查找已存储的文件。 ```python file_from_gridfs = fs.find_one({"filename": "example_file"}) if file_from_gridfs is not None: with open("/path/to/save/example_file", "wb") as output_file: output_file.write(file_from_gridfs.read()) # 将读取的内容写入本地磁盘 else: print("File not found.") ``` #### 删除文件 删除指定 ID 对应的文件及其关联的数据块。 ```python result = fs.delete(file_id) # 根据之前返回的对象ID执行删除动作 print(result) # 成功时无任何输出;失败会抛异常[^4] ``` #### 列出所有文件 查询当前存在于 GridFS 文件系统中的所有条目。 ```python for grid_data in fs.list(): print(grid_data) ``` 以上展示了如何利用 Python 脚本实现对 MongoDB 数据库存储大型文件的支持功能[^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值