pirosikick's diary

君のハートにunshift

でかいjsonをJSONStreamでちょっとずつTSVにする

小ネタ。

最近、ニフティクラウドのmobile backendにあるデータの集計を頼まれて、エクスポート機能で全てのデータをダウンロードしてとりあえずMySQLに入れようとしたんだけど、そのjsonが600MBくらいあってrequireで読み込めなかった。

$ cat hoge.js
var json = require('./big-data.json');

$ node hoge.js
FATAL ERROR: CALL_AND_RETRY_0 Allocation failed - process out of memory

こういう時のStreamなんだろうなーでも誰か実装してそうだなと思ったらやっぱりあった。

dominictarr/JSONStream · GitHub

{
  "results": [{ ... }, { ... } ・・・ ]
}

↑こういうJSONがあってresultsの中が欲しい場合、JSONStream.parse('results.*')でOK。

var fs = require('fs');
var _ = require('lodash');
var JSONStream = require('JSONStream');
var map = require('event-stream').map;

fs.createReadStream('./big-data.json')
  // JSONのroot["results"]
  .pipe(JSONStream.parse('results.*'))
  .pipe(map(function (data, callback) {
    // なんかしら処理する
    callback(null, _.values(data).join("\t") + "\n");
  }))
  .pipe(process.stdout);