でかい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);