Javascript 使用Nodejs在mongodb中存储文件

Javascript 使用Nodejs在mongodb中存储文件,javascript,node.js,mongodb,mongoose,Javascript,Node.js,Mongodb,Mongoose,我把文件保存在服务器的FS上,现在我想把它们保存在mongodb中。(为了更方便的备份和其他)。我想存储最大4-5Mb的文件,并尝试使用带缓冲区类型的mongoose保存它们。我成功地保存和检索了它们,但在保存和检索最大4或5Mb的文件时,我注意到性能非常慢 我的模式: let fileSchema = new Schema({ name: {type: String, required: true}, _announcement: {type: Schema.Types.ObjectId, r

我把文件保存在服务器的FS上,现在我想把它们保存在mongodb中。(为了更方便的备份和其他)。我想存储最大4-5Mb的文件,并尝试使用带缓冲区类型的mongoose保存它们。我成功地保存和检索了它们,但在保存和检索最大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));

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

我建议您使用
GridFS
它更快、更易于使用

有关详细信息,请检查此url:


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

似乎您正试图用mongoDb保存大量信息

我可以为你的情况考虑3种不同的选择

云服务
  • 正如其他人已经在这里评论的那样,如果您正在保存的文件是一个压缩文件,即使是一个小文件,新的压缩也不会帮助您。 在这种情况下,我的建议是使用一些web云服务,这些服务已经针对您试图保存和检索的信息类型进行了优化,如果您可以使用的图像也有免费服务,那么您可以对其进行测试
数据库中的本地存储和保存路由
  • 另一种解决方案可能是将编码数据存储在.txt文件中,将其存储在云或文件系统中,然后只将路由保存在数据库中。这样,您就不会依赖mongoDB的速度来检索它,但您将有一个很好的方法来知道文件的位置
使用MongoDB和GridFS
  • 通过这种方式,您可以使用特定的方法在MongoDB中存储信息,在处理16mb的文件时建议使用这种方法。 正如政府所说:
GridFS没有将文件存储在单个文档中,而是将文件分成多个部分或块[1],并将每个块存储为单独的文档。默认情况下,GridFS使用255kb的默认块大小;也就是说,GridFS将文件划分为255kb的块,最后一个块除外

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

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

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

希望它有用:)

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

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

值得关注的是,您有4mb的图像,除非您提供的图像对质量和分辨率有很大的依赖性——这是不应该发生的。请在存储图像之前压缩图像,在前端或后端(您的选择)进行压缩,如果在前端本身压缩图像,则会减少数据包的传输时间


对此没有明确的答案。这取决于您存储的数据类型?如果它是jpeg/png,它可能已经被压缩了,额外的压缩也不会有帮助。如果文件的大小很小,那么压缩也可能没有帮助。如果文件太大,则Next things DB不是一个好选项。@TarunLalwani,如果我错了,请纠正我。存储图像的标准方法是将图像存储在s3或cloudinary中(或者我猜imgur也可以),然后在DB中存储存储图像的URL吗?如果是这样的话,我很难理解为什么从外部网站的数据库检索数据要比我自己的快。在DB中存储没有意义,因为它们没有针对存储这些东西进行优化。而S3和Cloufront则针对此类文件、缓存和附近节点的服务进行了优化,以降低延迟和其他方面。这就是为什么使用外部服务是有意义的。但是,如果您想降低成本,您仍然可以选择mongodb,但这一成本将与您的代码一起投入到开发中。听起来您应该使用@TarunLalwani。有一个明确的答案——这就是:不要使用数据库来存储文件。。。在数据库之外存储文件,数据库应该存储的唯一内容是访问真实文件所需的信息,例如将其存储在AWS S3 bucket中。。。并将文件名和bucket名存储在DB字段中,这样无论谁访问它,都可以获得有关实际文件存储位置的信息,并可以在以后检索它。