V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
0bject
V2EX  ›  问与答

如何处理一个 1.5G 的 json

  •  
  •   0bject · 2020-01-30 07:00:33 +08:00 · 4868 次点击
    这是一个创建于 1756 天前的主题,其中的信息可能已经有所发展或是发生改变。

    json 的数据结构是:

    {
      "key1": {
        "key2": [
          { 200 多行各种结构}, 
          { 200 多行各种结构}, 
          { 200 多行各种结构},
          ...1.5G
        ]
      }
    }
    

    我想把数组全写进数据库, 服务器是前一阵 Oracle 1C1G 免费的...
    在我的 15 年 8g mac 上尝试过 stream-json, 结果奔溃了
    我想的最后的方法就是按行读, 可能也只能按行读了...

    第 1 条附言  ·  2020-01-30 16:46:34 +08:00

    随便在网上找了个数据

    {
      "a": {
        "b": [
          {
            "id": 301940,
            "slug": "ef4f2422125f",
            "nickname": "说",
            "avatar_source": "asdfsd",
            "total_likes_count": 28553,
            "total_wordage": 1373341,
            "is_following_user": false,
            "ob": {
              "a": 1,
              "b": 2
            }
          },
          {
            "id": 3950651,
            "slug": "ca5b9d6f94dc",
            "nickname": "三屿",
            "avatar_source": "asdf",
            "total_likes_count": 3625,
            "total_wordage": 169200,
            "is_following_user": false
          }
        ]
      },
      "total_count": 35932
    }
    

    我想用 js 来做,前面有几位仁兄说我的 stream-json 用的不对,我又回去改了改,发现还是不好用,我觉得我是哪块用的不对,我怎么才能只处理里面的 b 层数据,因为那个是数组,也是我需要的,谢谢

    我的代码如下,正在找方法拿里面的 b

    const { chain } = require("stream-chain");
    const { streamObject } = require("stream-json/streamers/StreamObject");
    const { streamArray } = require("stream-json/streamers/StreamArray");
    const Pick = require("stream-json/filters/Pick");
    const fs = require("fs");
    
    const pipeline = chain([
      fs.createReadStream("./small.json"),
      // fs.createReadStream("./big.json"),
      Pick.withParser({ filter: "a" }),
      streamObject(),
      // streamArray()
    ]);
    
    pipeline.on("data", data => {
      console.log(data);
    });
    pipeline.on("end", () =>
      console.log(`the end`)
    );
    
    
    第 2 条附言  ·  2020-01-31 06:44:41 +08:00

    解决了 是我的 filter 用的不对, 这是下面一位哥们的代码

    const { chain } = require("stream-chain");
    const { streamValues } = require("stream-json/streamers/StreamValues");
    const Pick = require("stream-json/filters/Pick");
    const fs = require("fs");
    
    const pipeline = chain([
      fs.createReadStream("./small.json"),
      Pick.withParser({ filter: /^a\.b\.\d+/ }),
      streamValues()
    ]);
    
    pipeline.on("data", data => {
        console.log(data);
    });
    
    pipeline.on("end", () => {
      console.log(`the end`);
    });
    
    29 条回复    2020-01-31 03:41:17 +08:00
    lichdkimba
        1
    lichdkimba  
       2020-01-30 07:11:12 +08:00 via iPhone
    别问 问就是加内存
    fuermosi777
        2
    fuermosi777  
       2020-01-30 07:12:24 +08:00   ❤️ 1
    我跑一个东西处理 60 多 G 的 json,用 go 自带的 json 包毫无压力
    noqwerty
        3
    noqwerty  
       2020-01-30 07:14:39 +08:00 via Android
    知道结构的话用 jq pipe 进去可以吗
    okchum
        4
    okchum  
       2020-01-30 07:19:10 +08:00   ❤️ 2
    LZ 我好像约莫着估计你是不是在某海外开车群
    sleepm
        5
    sleepm  
       2020-01-30 07:33:18 +08:00 via Android   ❤️ 1
    https://viewer.dadroit.com/
    可以查看也可以导出
    0bject
        6
    0bject  
    OP
       2020-01-30 08:17:51 +08:00
    @okchum 你...
    0bject
        7
    0bject  
    OP
       2020-01-30 08:20:33 +08:00
    @sleepm 我在电脑里也可以查看, 我想用程序读
    @noqwerty 谢谢 我去看看
    @fuermosi777 学不动了啊 秃顶了庶
    Maboroshii
        8
    Maboroshii  
       2020-01-30 08:21:34 +08:00 via Android
    python ijson
    gabon
        9
    gabon  
       2020-01-30 08:52:44 +08:00 via Android   ❤️ 4
    跟我读:bengkui 崩溃
    chinvo
        10
    chinvo  
       2020-01-30 08:56:07 +08:00 via iPhone
    在本地直接读进内存,插进库里导出 SQL 然后到服务器上执行
    0o0O0o0O0o
        11
    0o0O0o0O0o  
       2020-01-30 09:17:48 +08:00 via iPhone
    rapidjson 这些库有 SAX API
    prenwang
        12
    prenwang  
       2020-01-30 09:37:28 +08:00
    学习 elasticsearch 的 bulk , 逐行解析, 每行一个 json 对象,不要整个文件一个对象
    matrix67
        13
    matrix67  
       2020-01-30 09:37:55 +08:00
    @gabon 233333
    sinv
        14
    sinv  
       2020-01-30 10:13:50 +08:00 via Android
    @okchum #4 好像 约莫着 估计 是不是 某

    哈哈哈哈



    @0bject
    love
        15
    love  
       2020-01-30 12:18:53 +08:00
    整个结构是个 map ?这是什么逗逼设计,没法流式处理
    hammer86
        16
    hammer86  
       2020-01-30 12:24:19 +08:00 via iPhone
    @okchum 群号?我朋友想看看是不是同一个群
    azh7138m
        17
    azh7138m  
       2020-01-30 12:38:40 +08:00 via Android
    崩 beng 溃 kui
    stream-json 本身没有问题,一般是代码写的不对,为啥不直接给一下代码呢?
    wtks1
        18
    wtks1  
       2020-01-30 12:39:01 +08:00 via Android
    @love 看起来是电报群的命令行导出数据?
    Mutoo
        19
    Mutoo  
       2020-01-30 13:34:50 +08:00
    stream-json 边解析边写入数据库,解析完就 GC,只要不要在内存里留副本,不会有问题。
    billlee
        20
    billlee  
       2020-01-30 13:35:21 +08:00
    jackson/jsoniter 有流式处理 API.
    qiayue
        21
    qiayue  
       2020-01-30 13:38:12 +08:00
    hoyixi
        22
    hoyixi  
       2020-01-30 13:40:39 +08:00
    流处理应该没问题,看看是不是库的参数没调对。

    此外,JSONStream 也可以试试
    0bject
        23
    0bject  
    OP
       2020-01-30 14:57:30 +08:00
    @Mutoo 那可能是我没用对 我再去试试
    @sinv 你是哪个司机。。。
    @gabon 哈哈哈
    @hammer86 这又一个司机?
    @azh7138m 可能是我没用对 我再去试试
    @qiayue 谢谢
    @0o0O0o0O0o 谢谢
    @Maboroshii 谢谢
    @prenwang 谢谢
    多谢各位 新名词太多了 我去用 stream-json 再试试 然后我来贴代码
    20015jjw
        24
    20015jjw  
       2020-01-30 16:05:36 +08:00 via Android
    新的 mac pro 1.5t 内存能派上用场了..?
    (单位不一样
    0bject
        25
    0bject  
    OP
       2020-01-30 16:47:31 +08:00
    @azh7138m
    @Mutoo
    我把代码贴上了 谢谢
    eason1874
        26
    eason1874  
       2020-01-30 17:01:33 +08:00
    按行读的前提是你的数据是按行存,现在显然不是。

    像这种,我不知道有没有现成的轮子。如果让我处理的话,我会按块读取,比如每次读 1MB,正则提取出 JSON 格式字符串(剩下的放到下一块),然后解析。
    0bject
        27
    0bject  
    OP
       2020-01-30 17:04:10 +08:00
    @eason1874 有道理 如果我不能拿到 里面的一层 看来只能自己写了
    Mutoo
        28
    Mutoo  
       2020-01-30 19:14:46 +08:00
    @0bject 你的问题就是尝试去读整个数组,肯定会内存不足。以下 gist 这是我改的 demo 你可以参考一下。
    https://gist.github.com/mutoo/28667cfe7e9806ae4cfca9f348997f03
    0bject
        29
    0bject  
    OP
       2020-01-31 03:41:17 +08:00
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3140 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 14:16 · PVG 22:16 · LAX 06:16 · JFK 09:16
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.