V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
0bject
V2EX  ›  问与答

如何处理一个 1.5G 的 json

  •  
  •   0bject · Jan 30, 2020 · 5395 views
    This topic created in 2280 days ago, the information mentioned may be changed or developed.

    json 的数据结构是:

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

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

    Supplement 1  ·  Jan 30, 2020

    随便在网上找了个数据

    {
      "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`)
    );
    
    
    Supplement 2  ·  Jan 31, 2020

    解决了 是我的 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 replies    2020-01-31 03:41:17 +08:00
    lichdkimba
        1
    lichdkimba  
       Jan 30, 2020 via iPhone
    别问 问就是加内存
    fuermosi777
        2
    fuermosi777  
       Jan 30, 2020   ❤️ 1
    我跑一个东西处理 60 多 G 的 json,用 go 自带的 json 包毫无压力
    noqwerty
        3
    noqwerty  
       Jan 30, 2020 via Android
    知道结构的话用 jq pipe 进去可以吗
    okchum
        4
    okchum  
       Jan 30, 2020   ❤️ 2
    LZ 我好像约莫着估计你是不是在某海外开车群
    sleepm
        5
    sleepm  
       Jan 30, 2020 via Android   ❤️ 1
    https://viewer.dadroit.com/
    可以查看也可以导出
    0bject
        6
    0bject  
    OP
       Jan 30, 2020
    @okchum 你...
    0bject
        7
    0bject  
    OP
       Jan 30, 2020
    @sleepm 我在电脑里也可以查看, 我想用程序读
    @noqwerty 谢谢 我去看看
    @fuermosi777 学不动了啊 秃顶了庶
    Maboroshii
        8
    Maboroshii  
       Jan 30, 2020 via Android
    python ijson
    gabon
        9
    gabon  
       Jan 30, 2020 via Android   ❤️ 4
    跟我读:bengkui 崩溃
    chinvo
        10
    chinvo  
       Jan 30, 2020 via iPhone
    在本地直接读进内存,插进库里导出 SQL 然后到服务器上执行
    0o0O0o0O0o
        11
    0o0O0o0O0o  
       Jan 30, 2020 via iPhone
    rapidjson 这些库有 SAX API
    prenwang
        12
    prenwang  
       Jan 30, 2020
    学习 elasticsearch 的 bulk , 逐行解析, 每行一个 json 对象,不要整个文件一个对象
    matrix67
        13
    matrix67  
       Jan 30, 2020
    @gabon 233333
    sinv
        14
    sinv  
       Jan 30, 2020 via Android
    @okchum #4 好像 约莫着 估计 是不是 某

    哈哈哈哈



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

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

    像这种,我不知道有没有现成的轮子。如果让我处理的话,我会按块读取,比如每次读 1MB,正则提取出 JSON 格式字符串(剩下的放到下一块),然后解析。
    0bject
        27
    0bject  
    OP
       Jan 30, 2020
    @eason1874 有道理 如果我不能拿到 里面的一层 看来只能自己写了
    Mutoo
        28
    Mutoo  
       Jan 30, 2020
    @0bject 你的问题就是尝试去读整个数组,肯定会内存不足。以下 gist 这是我改的 demo 你可以参考一下。
    https://gist.github.com/mutoo/28667cfe7e9806ae4cfca9f348997f03
    0bject
        29
    0bject  
    OP
       Jan 31, 2020
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   5608 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 109ms · UTC 07:27 · PVG 15:27 · LAX 00:27 · JFK 03:27
    ♥ Do have faith in what you're doing.