0bject
V2EX  ›  问与答

如何处理一个 1.5G 的 json

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

    哈哈哈哈



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

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

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