• MongoDB-GridFS


    一、为什么使用GridFS

        GridFSMongoDB的一个子模块,使用GridFS可以基于MongoDB来持久存储文件,并且支持分布式应用(文件分布存储和读取)。作为MongoDB中二进制数据存储在数据库中的解决方案,通常用来处理大文件,对于MongoDBBSON格式的数据(文档)存储有尺寸限制,最大为16M。但是在实际系统开发中,上传的图片或者文件可能尺寸会很大,此时我们可以借用GridFS来辅助管理这些文件。

        GridFS不是MongoDB自身特性,只是一种将大型文件存储在MongoDB的文件规范,所有官方支持的驱动均实现了GridFS规范。GridFS制定大文件在数据库中如何处理,通过开发语言驱动来完成、通过API接口来存储检索大文件。

        GridFS的主要特性可以简单归纳为:

    MongoDB存储大文件。

    突破MongoDB单个文档最大16MB的限制。

    可以访问部分文件,而不用向内存中加载全部文件,从而保持高性能。

    文件和元数据自动同步。

    二、GridFS存储原理

    http://rdc.hundsun.com/portal/article/703.html

    三、使用GridFS

    1. 准备测试文件

    cat /usr/share/dict/words > /tmp/dictionary

    2. 查看MongoDB中的文件

    # /usr/local/mongodb/bin/mongofiles -u "root" -p "abc123" --authenticationDatabase admin list

    2019-06-20T00:02:24.851+0800 connected to: localhost

    list命令将列出数据库中的所有文件,当前数据库中没有任何文件。mongofiles是一个概念验证工具,主要用于学习和测试,而不应该在自己的应用中使用

    3. 将词典文件添加到数据库

    # /usr/local/mongodb/bin/mongofiles -u "root" -p "abc123" --authenticationDatabase admin -d gridfs put /tmp/dictionary

    2019-06-20T00:21:12.971+0800 connected to: localhost

    added file: /tmp/dictionary

    4. 再次查看MongoDB中的文件

    # /usr/local/mongodb/bin/mongofiles -u "root" -p "abc123" --authenticationDatabase admin -d gridfs list

    2019-06-20T00:25:35.600+0800 connected to: localhost

    /tmp/dictionary 4953680

    返回了词典文件及其大小,这些信息来自于files集合。MongoDB将文件拆分为块存储,默认的块大小为256K,可通过chunksize参数修改,但不能超过16MB的限制。put命令的返回信息中还包括文件上传时间戳,存储该文件在MongoDB中的创建时间

    5. 存储重名文件

    # /usr/local/mongodb/bin/mongofiles -u "root" -p "abc123" --authenticationDatabase admin -d gridfs put /tmp/dictionary

    2019-06-20T00:45:24.000+0800 connected to: localhost

    added file: /tmp/dictionary

    # /usr/local/mongodb/bin/mongofiles -u "root" -p "abc123" --authenticationDatabase admin -d gridfs list

    2019-06-20T00:45:29.287+0800 connected to: localhost

    /tmp/dictionary 4953680

    /tmp/dictionary 4953680

    put一遍同一文件,MongoDB中存储了两个同样的文件,它们的元数据一致,除了_id键。MongoDB提供了md5哈希算法,但GridFs不会自动处理md5值相同的文件。也就是说,同一个文件进行两次put命令,将会在GridFS中对应两个不同的存储,对于存储来说,这是一种浪费。对于md5相同的文件,如果想要在GridFS中只有一个存储,需要通过API进行扩展处理

    6. MongoDB中查看数据

    > use gridfs

    > show collections

    fs.chunks

    fs.files

    > db.fs.files.find()

    { "_id" : ObjectId("5d0a60f89ae80fadc9e0e42d"), "chunkSize" : 261120, "uploadDate" : ISODate("2019-06-19T16:21:13.446Z"), "length" : 4953680, "md5" : "15a189ff6eacf1796d56e2156d48d69a", "filename" : "/tmp/dictionary" }

    { "_id" : ObjectId("5d0a66a49ae80faee076fa89"), "chunkSize" : 261120, "uploadDate" : ISODate("2019-06-19T16:45:24.425Z"), "length" : 4953680, "md5" : "15a189ff6eacf1796d56e2156d48d69a", "filename" : "/tmp/dictionary" }

    > db.fs.chunks.find({},{"data":0})

    { "_id" : ObjectId("5d0a5d9d9ae80facf4177a1a"), "files_id" : ObjectId("5d0a5d9d9ae80facf4177a19"), "n" : 0 }

    { "_id" : ObjectId("5d0a5ee49ae80fad3d766145"), "files_id" : ObjectId("5d0a5ee49ae80fad3d766142"), "n" : 2 }

    { "_id" : ObjectId("5d0a5fd59ae80fad758882cf"), "files_id" : ObjectId("5d0a5fd59ae80fad758882ce"), "n" : 0 }

    { "_id" : ObjectId("5d0a5fd59ae80fad758882d0"), "files_id" : ObjectId("5d0a5fd59ae80fad758882ce"), "n" : 1 }

    { "_id" : ObjectId("5d0a5ee49ae80fad3d766143"), "files_id" : ObjectId("5d0a5ee49ae80fad3d766142"), "n" : 0 }

    { "_id" : ObjectId("5d0a60f89ae80fadc9e0e430"), "files_id" : ObjectId("5d0a60f89ae80fadc9e0e42d"), "n" : 2 }

    { "_id" : ObjectId("5d0a60f89ae80fadc9e0e42e"), "files_id" : ObjectId("5d0a60f89ae80fadc9e0e42d"), "n" : 0 }

    { "_id" : ObjectId("5d0a60f89ae80fadc9e0e42f"), "files_id" : ObjectId("5d0a60f89ae80fadc9e0e42d"), "n" : 1 }

    { "_id" : ObjectId("5d0a60f99ae80fadc9e0e432"), "files_id" : ObjectId("5d0a60f89ae80fadc9e0e42d"), "n" : 4 }

    { "_id" : ObjectId("5d0a60f99ae80fadc9e0e431"), "files_id" : ObjectId("5d0a60f89ae80fadc9e0e42d"), "n" : 3 }

    { "_id" : ObjectId("5d0a60f99ae80fadc9e0e433"), "files_id" : ObjectId("5d0a60f89ae80fadc9e0e42d"), "n" : 5 }

    { "_id" : ObjectId("5d0a60f99ae80fadc9e0e434"), "files_id" : ObjectId("5d0a60f89ae80fadc9e0e42d"), "n" : 6 }

    { "_id" : ObjectId("5d0a60f99ae80fadc9e0e435"), "files_id" : ObjectId("5d0a60f89ae80fadc9e0e42d"), "n" : 7 }

    { "_id" : ObjectId("5d0a60f99ae80fadc9e0e436"), "files_id" : ObjectId("5d0a60f89ae80fadc9e0e42d"), "n" : 8 }

    { "_id" : ObjectId("5d0a60f99ae80fadc9e0e437"), "files_id" : ObjectId("5d0a60f89ae80fadc9e0e42d"), "n" : 9 }

    { "_id" : ObjectId("5d0a60f99ae80fadc9e0e438"), "files_id" : ObjectId("5d0a60f89ae80fadc9e0e42d"), "n" : 10 }

    { "_id" : ObjectId("5d0a60f99ae80fadc9e0e439"), "files_id" : ObjectId("5d0a60f89ae80fadc9e0e42d"), "n" : 11 }

    { "_id" : ObjectId("5d0a60f99ae80fadc9e0e43a"), "files_id" : ObjectId("5d0a60f89ae80fadc9e0e42d"), "n" : 12 }

    { "_id" : ObjectId("5d0a60f99ae80fadc9e0e43b"), "files_id" : ObjectId("5d0a60f89ae80fadc9e0e42d"), "n" : 13 }

    { "_id" : ObjectId("5d0a60f99ae80fadc9e0e43c"), "files_id" : ObjectId("5d0a60f89ae80fadc9e0e42d"), "n" : 14 }

    Type "it" for more

    数据库中生成了fs.filesfs.chunks两个集合。files存储文件元数据信息,chunks存储文件中的数据

    7. 使用搜索命令

    1)上传一个新文件

    # cp /tmp/dictionary /tmp/hello_world

    # /usr/local/mongodb/bin/mongofiles -u "root" -p "abc123" --authenticationDatabase admin -d gridfs put /tmp/hello_world

    2019-06-20T01:01:05.191+0800 connected to: localhost

    added file: /tmp/hello_world

    # /usr/local/mongodb/bin/mongofiles -u "root" -p "abc123" --authenticationDatabase admin -d gridfs list

    2019-06-20T01:01:12.907+0800 connected to: localhost

    /tmp/dictionary 4953680

    /tmp/dictionary 4953680

    /tmp/hello_world 4953680

    2)用search命令搜索文件名

    # /usr/local/mongodb/bin/mongofiles -u "root" -p "abc123" --authenticationDatabase admin -d gridfs search hell

    2019-06-20T01:03:49.818+0800 connected to: localhost

    /tmp/hello_world 4953680

    # /usr/local/mongodb/bin/mongofiles -u "root" -p "abc123" --authenticationDatabase admin -d gridfs search ict

    2019-06-20T01:03:59.045+0800 connected to: localhost

    /tmp/dictionary 4953680

    /tmp/dictionary 4953680

    8. 删除MongoDB中的文件

    # /usr/local/mongodb/bin/mongofiles -u "root" -p "abc123" --authenticationDatabase admin -d gridfs delete /tmp/dictionary

    2019-06-20T01:07:33.195+0800 connected to: localhost

    successfully deleted all instances of '/tmp/dictionary' from GridFS

    # /usr/local/mongodb/bin/mongofiles -u "root" -p "abc123" --authenticationDatabase admin -d gridfs list

    2019-06-20T01:07:42.647+0800 connected to: localhost

    /tmp/hello_world 4953680

    使用delete命令有两点需要注意:

    该命令基于文件名删除文件,因此将删除所有同名文件。

    MongoDB不会释放已经占用的硬盘空间。即使删除db中的集合MongoDB也不会释放磁盘空间。同样,如果使用GridFS存储文件,从GridFS存储中删除无用的垃圾文件,MongoDB依然不会释放磁盘空间的。这会造成磁盘一直在消耗,而无法回收利用的问题。

    9. MongoDB中获取文件

    # /usr/local/mongodb/bin/mongofiles -u "root" -p "abc123" --authenticationDatabase admin -d gridfs get /tmp/hello_world

    2019-06-20T01:11:08.444+0800 connected to: localhost

    finished writing to /tmp/hello_world

  • 相关阅读:
    Redux 学习总结
    ECMAScript 6 学习总结
    Bootstrap 前端UI框架
    React.js 学习总结
    html 之 <meta> 标签之http-equiv
    Leetcode Excel Sheet Column Number (C++) && Excel Sheet Column Title ( Python)
    490
    414
    494
    458
  • 原文地址:https://www.cnblogs.com/allenhu320/p/11340096.html
Copyright © 2020-2023  润新知