MongoDB之GridFS
1. GridFS的作用
GridFS 用于存储和恢复那些超过16M(BSON文件限制)的文件(如:图片、音频、视频等)。
GridFS 也是文件存储的一种方式,但是它是存储在MonoDB的集合中。
GridFS 会将大文件对象分割成多个小的chunk(文件片段),一般为256k/个,每个chunk将作为MongoDB的一个文档(document)被存储在chunks集合中。
当你从GridFS查询文件时,驱动程序将根据需要重新组装该文件所有的块。你可以对GridFS存储的文件进行范围查询。你还可以从文件的任意部分访问其信息,例如“跳到”视频或音频文件的中间
2. 什么时候使用GridFS
当文件大于16MB时
当你要访问大文件部分的信息而不必将整个文件加载到内存中时,可以使用GridFS来调用文件的某些部分,而无需将整个文件读入内存
当你希望保持文件和元数据在多个系统和设施之间自动同步和部署时,可以使用GridFS
注意:
如果您需要对整个文件的内容进行原子更新,请不要使用GridFS。
如果文件均小于16 MB BSON文档大小限制,请考虑将每个文件存储在单个文档中,而不是使用GridFS。
3. 如何使用GridFS
MongoDB驱动程序
mongofiles命令行工具
1. 选项参数
--version
-h hostname:port
-d databasename
2. 命令参数
list
mongofiles -h 192.168.2.232:16535 -d yangjianbo list
put
mongofiles -h 192.168.2.232:16535 -d yangjianbo put IMG_0047.mp4
get
mongofiles -h 192.168.2.232:16535 -d yangjianbo get IMG_0047.mp4
delete
mongofiles -h 192.168.2.232:16535 -d yangjianbo delete IMG_0047.mp4
4. GridFS Collections
GridFS 用两个集合来存储一个文件:fs.chunks与fs.files
fs.chunks存储二进制块
fs.files存储文件的元数据
1. fs.chunks
{
"_id" : <ObjectId>,
"files_id" : <ObjectId>,
"n" : <num>,
"data" : <binary>
}
chunks._id
块的唯一ObjectId。
chunks.files_id
在files集合中指定的“父”文档的_id。
chunks.n
块的序列号。 GridFS从0开始对所有块进行编号。
chunks.data
块BSON二进制类型的荷载。
2. fs.files
{
"_id" : <ObjectId>,
"length" : <num>,
"chunkSize" : <num>,
"uploadDate" : <timestamp>,
"md5" : <hash>,
"filename" : <string>,
"contentType" : <string>,
"aliases" : <string array>,
"metadata" : <any>,
}
files._id
该文档的唯一标识符。 _id是您为原始文档选择的数据类型。 MongoDB文档的默认类型是BSON ObjectId。
files.length
文档的大小(以字节为单位)。
files.chunkSize
每个块的大小(以字节为单位)。 GridFS将文档分为大小为chunkSize的块,最后一个除外,后者仅根据需要而变大。默认大小为255 KB。
files.uploadDate
GridFS首次存储这个文档的日期。此值为有日期类型。
files.md5
过期
FIPS 140-2禁止使用MD5算法。 MongoDB驱动程序已弃用MD5支持,并将在未来版本中删除MD5的生成。需要文件摘要的应用程序应在GridFS外部实现它,并将其存储在files.metadata中。
filemd5命令返回的完整文件的MD5哈希。此值为字符串类型。
files.filename
可选的。GridFS文件的可读名称。
files.contentType
过期
可选的。GridFS文件的有效MIME类型。仅应用程序用。
使用files.metadata来存储与GridFS文件的MIME类型有关的信息。
files.aliases
过期
可选的。别名字符串数组。仅用于应用程序
使用files.metadata来存储与GridFS文件的MIME类型有关的信息。
files.metadata
可选的。元数据字段可以是任何数据类型,并且可以保存您要存储的任何其他信息。如果希望将其他任意字段添加到文件集合中的文档,请将其添加到元数据字段中的对象。
5. GridFS索引
1. chunks索引
GridFS使用files_id和n字段在chunks集合上使用唯一的复合索引
db.fs.chunks.find( { files_id: myFileID } ).sort( { n: 1 } )
驱动程序会自动创建该索引;如果不存在,手工创建: db.fs.chunks.createIndex( { files_id: 1, n: 1 }, { unique: true } );
2. files索引
GridFS在files集合上的filename和uploadDate字段上使用索引
db.fs.files.find( { filename: myFileName } ).sort( { uploadDate: 1 } )
驱动程序会自动创建该索引;如果不存在,手工创建: db.fs.files.createIndex( { filename: 1, uploadDate: 1 } );
6. 分片GridFS
1. chunks集合
要分片chunks集合,请使用{ files_id : 1, n : 1 } 或{ files_id : 1 } 作为分片键索引。 files_id是一个ObjectId,并且单调更改。
2. files集合
集合很小,不需要分片
如果必须分片 files集合,请使用_id字段,可能与应用程序字段结合使用
7. GridFS 添加文件
现在我们使用 GridFS 的 put 命令来存储 mp3 文件。 调用 MongoDB 安装目录下bin的 mongofiles.exe工具。
打开命令提示符,进入到MongoDB的安装目录的bin目录中,找到mongofiles.exe,并输入下面的代码:
>mongofiles.exe -d gridfs put song.mp3
GridFS 是存储文件的数据名称。如果不存在该数据库,MongoDB会自动创建。Song.mp3 是音频文件名。
使用以下命令来查看数据库中文件的文档:
>db.fs.files.find()
以上命令执行后返回以下文档数据:
{
_id: ObjectId('534a811bf8b4aa4d33fdf94d'),
filename: "song.mp3",
chunkSize: 261120,
uploadDate: new Date(1397391643474), md5: "e4f53379c909f7bed2e9d631e15c1c41",
length: 10401959
}
我们可以看到 fs.chunks 集合中所有的区块,以下我们得到了文件的 _id 值,我们可以根据这个 _id 获取区块(chunk)的数据:
>db.fs.chunks.find({files_id:ObjectId('534a811bf8b4aa4d33fdf94d')})
以上实例中,查询返回了 40 个文档的数据,意味着mp3文件被存储在40个区块中。

浙公网安备 33010602011771号