【问题标题】:Store files in mongodb with Nodejs使用 Nodejs 在 mongodb 中存储文件
【发布时间】:2018-01-01 00:22:24
【问题描述】:

我将文件保存在服务器的 FS 上,现在我想将它们保存在 mongodb 中。(以便于备份和东西)。我想存储最大 4-5Mb 的文件,我尝试用 mongoose 保存它们使用 Buffer 类型。我成功保存并检索了它们,但是当我保存和检索 4 或 5Mb 等文件时,我注意到性能显着降低。

我的架构:

let fileSchema = new Schema({
name: {type: String, required: true},
_announcement: {type: Schema.Types.ObjectId, ref: 'Announcements'},
data: Buffer,
contentType: String
});

我如何从 expressjs 服务器中检索它们:

 let name = encodeURIComponent(file.name);
 res.writeHead(200, {
     'Content-Type': file.contentType,
     'Content-Disposition': 'attachment;filename*=UTF-8\'\'' + name
 });
 res.write(new Buffer(file.data));

我的问题是我是否应该使用一些 zlib 压缩函数(如“deflate”)在将缓冲区保存到 mongodb 之前对其进行压缩,然后在将二进制文件发送到客户端之前对其进行解压缩?这会让整个过程更快吗?我错过了什么吗?

【问题讨论】:

  • 对此没有明确的答案。这取决于您存储的数据类型?如果它是 jpeg/png,它可能已经被压缩并且额外的压缩将无济于事。如果文件的大小很小,那么它也可能无助于压缩。如果文件很大,接下来的事情 DB 不是很好的选择。
  • @TarunLalwani,如果我错了,请纠正我。存储图像的标准方法是将图像存储在 s3 还是 cloudinary 中,(或者我猜甚至 imgur 也可以)然后在 DB 中存储所存储图像的 URL?如果是这样的话,我很难理解为什么从外部网站的数据库中检索数据比我自己的要快。
  • 在 DB 中存储没有意义,因为它们没有针对存储此类内容进行优化。虽然 S3 和 Cloufront 针对提供此类文件、缓存、附近节点以降低延迟和一切进行了优化。这就是使用外部服务有意义的原因。但是如果你想降低成本,你仍然可以选择 mongodb,但是这个成本会随着你的代码本身投入到开发中
  • 听起来你应该使用GridFS
  • @TarunLalwani 有一个明确的答案 - 正是这样:不要使用数据库来存储文件......将文件存储在数据库之外,数据库应该存储的唯一内容是访问真实所需的信息文件,例如将其存储在 AWS S3 存储桶中......并将文件名和存储桶名称存储在 DB 字段中,以便访问它的人获取有关实际文件存储位置的信息,并可以在以后检索它。

标签: javascript node.js mongodb mongoose


【解决方案1】:

我会建议你使用GridFS,它更快且非常易于使用。

欲了解更多信息,请查看此网址:https://docs.mongodb.com/manual/core/gridfs/

如果您对GridFS 有任何疑问,请告诉我。

【讨论】:

    【解决方案2】:

    您似乎正在尝试使用 mongoDb 保存大量信息。

    我可以根据您的情况考虑 3 个不同的选项

    云服务

    • 正如其他人已经在这里评论的那样,如果您保存的文件是压缩文件,即使它是一个小文件,新的压缩也不会帮助您。 在这种情况下,我的建议是使用一些网络云服务,该服务已经针对您尝试保存和检索的信息进行了优化,如果它是图像,您可以使用Cloudinary,它也有免费服务,所以您可以测试一下。

    本地存储和在数据库中保存路由

    • 其他解决方案可能是将编码数据存储在 .txt 文件中,将其存储在云端或文件系统中,然后仅将路由保存在数据库中。这样,您将不会依赖 mongoDB 的速度来检索它,但您将有一个很好的方法来了解文件的位置。

    使用 MongoDB 和 GridFS

    • 通过这种方式,您可以使用特定方法将信息存储在 MongoDB 中,当您处理 16mb 的文件时建议使用该方法。 正如Official Documentation 所说:

    GridFS 不是将文件存储在单个文档中,而是将文件分成部分或块 [1],并将每个块存储为单独的文档。默认情况下,GridFS 使用 255 kB 的默认块大小;也就是说,GridFS 将一个文件分成 255 kB 的块,除了最后一个块。

    接下来他们说在什么情况下你可以使用这种存储信息的方式:

    在某些情况下,在 MongoDB 数据库中存储大文件可能比在系统级文件系统中更有效。

    • 如果您的文件系统限制了目录中的文件数量,您可以使用 GridFS 存储所需数量的文件。
    • 如果您想从大文件的一部分中访问信息而不必将整个文件加载到内存中,您可以使用 GridFS 来调用文件的各个部分,而无需将整个文件读入内存。
    • 当您希望在多个系统和设施中自动同步和部署文件和元数据时,可以使用 GridFS。使用地理分布的副本集时,MongoDB 可以自动将文件及其元数据分发到多个 mongod 实例和设施。

    希望有用:)

    【讨论】:

      【解决方案3】:

      如果您绝对认为必须将图像存储在数据库中,而不是存储在文件系统或其他云服务中,我不会对此发表评论。

      关于您的具体问题,GridFS 是人们在生产中使用的一个受人尊敬的选择,并且很好地达到了它的目的。几年前我亲自使用过它,但我的用例发生了变化,因此转移到了另一种媒体。 (请查看人们讨论其性能的 SO 链接)

      令人担忧的是,您拥有 4mb 的图像,除非您提供的图像非常依赖质量和大分辨率 - 这不应该发生。请在存储之前压缩您的图像,在前端或后端进行(您的选择),如果您在前端本身压缩它们,则会减少数据包的传输时间。

      Discussion on scale of GridFS

      Module for node.js side compression

      GridFS

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-01-25
        • 1970-01-01
        • 1970-01-01
        • 2012-07-11
        • 2014-05-11
        • 2013-10-27
        • 1970-01-01
        • 2015-11-08
        相关资源
        最近更新 更多