1.GridFS介绍
1.1Why use GridFS?
由于MongoDB中BSON对象大小是有限制的,所以GridFS 规范提供了一种透明的机制,可以将一个大文件分割成为多个较小的文档,这样的机制允许我们有效的保存大文件对象,特别对于那些巨大的文件,比如视频、高清图片等。
为实现这点,该规范指定了一个将文件分块的标准。每个文件都将在文件集合对象中保存一个元数据对象,一个或多个chunk块对象可被组合保存在一个chunk块集合中。
GridFS是Mongo的一个子模块,使用GridFS可以基于MongoDB来持久存储文件。并且支持分布式应用(文件分布存储和读取)。作为MongoDB中二进制数据存储在数据库中的解决方案,通常用来处理大文件,对于MongoDB的BSON格式的数据(文档)存储有尺寸限制,最大为16M。但是在实际系统开发中,上传的图片或者文件可能尺寸会很大,此时我们可以借用GridFS来辅助管理这些文件。
<使用场景>
▲如果您的文件系统在一个目录中存储的文件的数量有限,你可以使用GridFS存储尽可能多的文件。
▲当你想访问大型文件的部分信息,却不想加载整个文件到内存时,您可以使用GridFS存储文件,并读取文件部分信息,而不需要加载整个文件到内存。
▲当你想让你的文件和元数据自动同步并部署在多个系统和设施,你可以使用GridFS实现分布式文件存储。
GridFS不是MongoDB自身特性,只是一种将大型文件存储在MongoDB的文件规范,所有官方支持的驱动均实现了GridFS规范。GridFS制定大文件在数据库中如何处理,通过开发语言驱动来完成、通过API接口来存储检索大文件。
GridFS使用两个集合(collection)存储文件。
- chunks, 用于存储文件内容的二进制数据;
-
files,用于存储文件的元数据。
GridFS会将两个集合放在一个普通的buket中,并且这两个集合使用buket的名字作为前缀。MongoDB的GridFs默认使用fs命名的buket存放两个文件集合。因此存储文件的两个集合分别会命名为集合fs.files ,集合fs.chunks。
当然也可以定义不同的buket名字,甚至在一个数据库中定义多个bukets,但所有的集合的名字都不得超过mongoDB命名空间的限制。
MongoDB集合的命名包括了数据库名字与集合名字,会将数据库名与集合名通过“.”分隔(eg:< database>.< collection>)。而且命名的最大长度不得超过120bytes。
当把一个文件存储到GridFS时,如果文件大于chunksize (每个chunk块大小为256KB),会先将文件按照chunk的大小分割成多个chunk块,最终将chunk块的信息存储在fs.chunks集合的多个文档中。然后将文件信息存储在fs.files集合的唯一一份文档中。其中fs.chunks集合中多个文档中的file_id字段对应fs.files集中文档”_id”字段。
读文件时,先根据查询条件在files集合中找到对应的文档,同时得到“_id”字段,再根据“_id”在chunks集合中查询所有“files_id”等于“_id”的文档。最后根据“n”字段顺序读取chunk的“data”字段数据,还原文件。
fs.files 集合存储文件的元数据,以类json格式文档形式存储。每在GridFS存储一个文件,则会在fs.files集合中对应生成一个文档。
▲fs.files集合中文档的存储内容如下:
fs.chunks 集合存储文件文件内容的二进制数据,以类json格式文档形式存储。每在GridFS存储一个文件,GridFS就会将文件内容按照chunksize大小(chunk容量为256k)分成多个文件块,然后将文件块按照类json格式存在.chunks集合中,每个文件块对应fs.chunk集合中一个文档。一个存储文件会对应一到多个chunk文档。
▲ fs.chunks集合中文档的存储内容如下:
为了提高检索速度 MongoDB为GridFS的两个集合建立了索引。fs.files集合使用是“filename”与“uploadDate” 字段作为唯一、复合索引。fs.chunk集合使用的是“files_id”与“n”字段作为唯一、复合索引
2.将文件添加到GridFS:
<使用shell命令>
mongoDB提供mingofiles工具,可以下面命令行来操作GridFS。
现在,我们将使用GridFS的put命令存储zip文件。 为此,我们将使用存在于MongoDB的安装文件夹下的bin文件夹的mongofiles.exe工具。
打开命令提示符,导航到MongoDB的安装文件夹下的bin文件夹中的mongofiles.exe,并键入下面的代码:
这些命令都是按照filename操作GridFS中存储的文件的。
>mongofiles.exe -d gridfs put F:\\iTunes64Setup_12.7.0.166.zip
这里,gridfs上在文件存储在数据库的数据库名称。 如果数据库不存在,MongoDB会自动动态创建一个集合(gridfs)
注:NoSQL Manager for MongoDB 是 MongoDB 可视化工具
>db.fs.files.find()
上面的命令返回以下文档:
{
“_id” : ObjectId(“5b7d272864aa346018c52062”),
“chunkSize” : 261120,
“uploadDate” : ISODate(“2018-08-22T09:04:43.776Z”),
“length” : 260551736,
“md5” : “424a1fb49ec3ba0b669f3fb0b9bb90b0”,
}
我们也可以看到在fs.chunks集合涉及使用下面的代码保存的文件都存在于块中,使用以前的查询返回文档ID:
db.fs.chunks.find({files_id:ObjectId(‘534a811bf8b4aa4d33fdf94d’)})
该查询返回999个文档,是整个zip文件划分成的999块数据。
https://blog.csdn.net/yangyatou1991/article/details/71330923