javascript - 如何使用 GridFs 保存 JSON 文件

标签 javascript json mongodb mongoose

我有一个巨大的数据集,我正在使用 Mongoose 模式,每个数据元素看起来像这样:

    {
      field1: “>HWI-ST700660_96:2:1101:1455:2154#5@0/1”: 
      field2: “GAA…..GAATG”

    }

来源:Reading an FASTA file

如您所见,单个元素简单而小,但数量巨大!它们加起来将超过 200MB。

问题是:我无法将它保存到 mongo,因为它太大(> 200MB) .

尽管如此,我还是找到了 GridF,
  • 到目前为止,我发现的所有 Material 都是关于图像和视频上传的;
  • 他们没有说我如何仍然可以使用 Mongoose 模式功能;
  • 到目前为止,我所看到的示例并没有将数据保存到用户定义的路径中,就像我们使用 mongoose 所做的那样。

  • 在最简单的场景中:如何使用 GridFS 或任何类似的解决方案来保存 JSON 文件,就像我使用小型 JSON 文件一样。与其他方法相比,这种方法有哪些优点和缺点(如果有的话)?你认为我的方法有效吗?我的意思是,我在这里提到的那个,使用 JSON 文件树和 populate后来,它工作!

    作为使用 mongoose 保存 JSON 文件的示例:
    Model.create([        
              {
              field1: “>HWI-ST700660_96:2:1101:1455:2154#5@0/1”: 
              field2: “GAA…..GAATG”
    
            }, 
            {
              field1: “>HWI-ST700660_96:2:1101:1455:2154#5@0/1”: 
              field2: “GAA…..GAATG”
    
            }]);
    

    在这里,我刚刚保存了一个包含两个元素的 JSON 文件,我不能用一个巨大的文件来做到这一点,我需要分成更小的部分(比如 1% 的 block ),并创建刚才提到的树,至少这是我的解决方案。

    恐怕我正在重新发明轮子。我可以独立保存这些文件,它可以工作,但我需要保持它们的相关性,因为它们属于同一个文件,就像图像的较小块属于同一个图像一样。

    恐怕我正在重新发明轮子。

    当前解决方案

    这是我目前的解决方案,使用我自己的见解!看到我在这里提到只是出于好奇,它不使用 GridFS,因此,我仍然愿意接受使用 GridFS 的建议。它只使用 JSON 文件,并将文档分成更小的文件,就像层次结构一样。它是一棵树,我只想要溶液中的叶子。

    enter image description here

    我已经解决了问题尽管如此,出于学习目的,使用此图,我想看看是否可以使用 GridFS 来做同样的事情。

    讨论

    我的第一种方法是将它们保留为 subdoc:它失败了!然后我试图只保留他们的 id,他们的 id 对应于整个 block 的 35%,并且大于 16MB:失败!然后我决定创建一个虚拟文档,只是为了保留 id,并只存储虚拟文档的 id:成功!

    最佳答案

    很可能不值得使用 GridFS 将数据存储在 Mongo 中。

    二进制数据从不真正属于数据库,但如果数据很小,将其放入数据库(查询能力)的好处大于缺点(服务器负载,速度慢)。

    在这种情况下,您似乎希望将文档数据 (JSON) 存储在 GridFS 中。您可以这样做,并以存储任何其他二进制数据的方式存储它。然而,数据将是不透明的。您不能查询存储在 GridFS 文档中的 JSON 数据,只能查询文件元数据。

    查询大数据

    正如您提到的要查询数据,您应该检查数据的格式。如果您的数据采用示例中列出的格式,那么似乎不需要复杂的查询,只需要字符串匹配。所以有几种选择。

    案例一:大数据,少点

    如果您的数据集不多(field1field2 对),但每个数据集都很大(field2 包含许多字节),请将它们存储在其他地方并仅存储对其的引用。一个简单的解决方案是将数据(以前的 field2)存储在 Amazon S3 上的文本文件中,然后存储然后存储链接。例如

    {
      field1: “>HWI-ST700660_96:2:1101:1455:2154#5@0/1”,
      field2link: "https://my-bucket.s3.us-west-2.amazonaws.com/puppy.png"
    }
    

    案例二:小数据,多点

    如果您的每个数据集都很小(小于 16 MB)但有很多数据集,请将您的数据存储在 MongoDB(没有 GridFS)中。

    细节

    在您的情况下,数据非常大,不建议使用 GridFS 存储它。

    This answer为底部提供了基准。基准似乎表明检索时间或多或少与文件大小成正比。使用相同的设置,从数据库中检索文档需要 80 秒。

    可能的优化

    GridFS 中的默认 block 大小为 255 KiB。您可以通过将 block 大小增加到最大值 (16 MB) 来减少大文件访问时间。如果 block 大小是唯一的瓶颈,那么使用 16 MB block 大小会将检索时间从 80 秒减少到 1.3 秒 (80/(16MB/255KiB) = 1.3)。您可以在初始化 GridFS 存储桶时执行此操作。
    new GridFSBucket(db, {chunkSizeBytes: 16000000})
    

    更好的策略是将唯一的文件名存储在 Mongo 中,然后从文件系统中检索文件。

    其他缺点

    在 Mongo 中存储二进制数据的另一个可能的缺点来自 this site :
    “如果二进制数据很大,那么将二进制数据加载到内存中可能会导致频繁访问的文本(结构化数据)文档被挤出内存,或者更一般地说,工作集可能无法放入 RAM。这会对数据库的性能。” [ 1 ]

    例子

    在 GridFS 中保存文件,改编自 Mongo GridFS tutorial
    const uri = 'mongodb://localhost:27017/test';
    
    mongodb.MongoClient.connect(uri, (error, db) => {
      const bucket = new mongodb.GridFSBucket(db);
    
      fs.createReadStream('./fasta-data.json')
        .pipe(bucket.openUploadStream('fasta-data.json'))
        .on('finish', () => console.log('done!'))
      ;
    });
    

    关于javascript - 如何使用 GridFs 保存 JSON 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60968353/

    相关文章:

    laravel 5.3中mysql和mongodb的关系

    javascript - 设置 Webpack 和 Babel 的问题

    javascript - VueJ 中的过滤器

    javascript - 从 javascript 更改输入值属性

    json - 无法在 golang 中解析此 json 文件

    javascript - mongodb/mongoose 中的保存方法

    javascript - 如何在动态方法中更改列的宽度

    javascript - JSON to Go结构

    javascript - 使用 XPath 样式访问 Javascript JSON 对象属性

    python json 自定义解码 LONG