【问题标题】:Storing data url in Mongo DB在MongoDB中存储数据url
【发布时间】:2014-02-14 10:17:35
【问题描述】:

我正在考虑将data-urls 存储在我的 mongoDB 中而不是存储对文件的引用或使用 GridFS。

数据地址:

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMcAAAEsCAYAAAB38aczAAAgAElEQV

我存储的所有文件都是 JPG 或 PNG,大小小于 1MB。

我想知道这是否被认为是不好的做法,以及将data-urls 1) 存储在单独的集合中 2) 作为集合中的元数据对读取和写入操作的性能影响。

我愿意接受有关小文件存储的任何其他建议。

【问题讨论】:

    标签: mongodb data-url


    【解决方案1】:

    首先,我不会将 base64 编码数据存储在完全能够存储二进制数据的数据库中。那只是浪费空间。存储图像本身,而不是它的base64表示,即不是data : "VBORw0KGgoAAAANSUhEUgAAA...",而是data : BinData("VBORw0KGgoAAAANSUhEUgAAA...")(前者是MongoDB的字符串,后者是二进制数据)。 Base64 将大小增加了 33%。

    除此之外,我认为这很好。权衡是获取所有数据的 1 个请求与多个请求。存储较大数据块的缺点是所有数据必须暂时在 RAM 中,但在 1MB 时这可能不是问题。

    但是,您应该确保不要在不需要图像的情况下获取文档。 1MB 不算多,但对于读取量大的集合来说,这简直是一场灾难。

    【讨论】:

    • 谢谢。在我的情况下,很少需要抓取图像,并且对集合执行了几个读取繁重的查询。我认为为所有现有查询指定排除项不是一个好主意。所以看起来我的选择是 1) 只将图像存储在我的文件服务器上,2) 将二进制数据存储在单独的集合中,创建 refs,并在必要时使用 mongoose 的填充来获取图像。
    • 听起来单独的集合最适合。我在一个调用辅助集合的宠物项目中使用了相同的概念...Images ;-) 效果很好,对于这种使用模式,它比 GridFS 更好
    • 很高兴知道您在这项技术上取得了成功。再次感谢 mnemosyn 提供的知识。
    【解决方案2】:

    我刚刚完成了一个解决方案。此解决方案适用于 Ajax,因此您可以在 Javascript 中使用 fetch 调用。奇怪的是,在整个互联网上都找不到这个解决方案,这就是为什么我要帮助其他想要使用数据 uri 处理图像的人:-)

    型号

            cmsImage: { data: Buffer, contentType: String }
    

    存储在 MongoDB 中:

            let rawData = fs.readFileSync(`${root}public/uploads/` + file.originalname);
            let base64Data = Buffer.from(rawData).toString('base64');
    
            // upload this image
            let image = { 
                cmsImage: {
                    data: base64Data,
                    contentType: file.mimetype
                }    
            };
    
            // in this record in the database
            await this.model.findByIdAndUpdate(body.id, image);        
    

    从 MongoDB 中检索并动态创建图像元素:

           // decode image from database as image uri
           let imageArray = new Int8Array(image.data.data);
           let decodedImage = new TextDecoder().decode(imageArray);
    
           // image
           let cmsImage = document.createElement("img");
           cmsImage.src = "data:" + image.contentType + ";base64," + decodedImage;
           cmsImage.alt = "image";
           cmsContent.appendChild(cmsImage);
    

    Multer - 使用原始文件上传到数据库。

          let storage = multer.diskStorage({
            destination: function (req, file, cb) {
              cb(null, './public/uploads')
            },
            filename: function (req, file, cb) {
              cb(null, file.originalname)
            }
          });
    
          this.upload = multer({ storage: storage });
    

    上传到目录

          this.upload.single(uploadImage)
    
      
    

    【讨论】:

      猜你喜欢
      • 2021-06-10
      • 1970-01-01
      • 2014-11-02
      • 2011-05-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-09
      • 2016-02-17
      相关资源
      最近更新 更多