2

JSON に格納されたユーザー テーブルを表す Firebase データベースのダンプがあります。データ分析を実行したいのですが、大きすぎてメモリに完全にロードして、純粋な JavaScript (または_同様のライブラリ) で操作できないという問題があります。

これまで、JSONStreamパッケージを使用して、データを一口サイズのチャンクで処理してきました (JSON ダンプ内のユーザーごとに 1 回コールバックを呼び出します)。

ただし、値に基づいてユーザー ID をフィルター処理したいため、障害が発生しました。私が答えようとしている「質問」は、「どのユーザー x」という形式のものですが、以前は「何人のユーザー x」と尋ねるだけで、彼らが誰であるかを知る必要はありませんでした。

データ形式は次のようになります。

{
    users: {
        123: {
            foo: 4
        },
        567: {
            foo: 8
        }
    }
}

私がやりたいことは、基本的に の値に基づいてユーザー ID (123または上記) を取得することです。これが小さなリストである場合、キーと値を反復処理して必要なキーを抽出するようなものを使用するのは簡単です。567foo_.each

残念ながら、メモリに収まらないため、機能しません。JSONStream を使用するvar parser = JSONStream.parse('users.*');と、次のようにそれを処理する関数を使用してパイプすることで、それを反復処理できます。

var stream = fs.createReadStream('my.json');

stream.pipe(parser);

parser.on('data', function(user) {
    // user is equal to { foo: bar } here
    // so it is trivial to do my filter
    // but I don't know which user ID owns the data
});

しかし、問題は、渡したスター ワイルドカードを表すキーにアクセスできないことですJSONStream.parse{ foo: bar}つまり、 がuser なの123か userなのかわかりません567

質問は 2 つあります。

  1. コールバック内から現在のパスを取得するにはどうすればよいですか?
  2. 大きすぎてメモリに収まらないこの JSON データを処理するより良い方法はありますか?
4

1 に答える 1

4

JSONStream を編集して、この機能を追加しました。

誰かがこれに出くわし、同様にパッチを適用したい場合は、line 83以前のものを置き換えることができます

stream.queue(this.value[this.key])

これとともに:

var ret = {};
ret[this.key] = this.value[this.key];

stream.queue(ret);

元の質問のコード サンプルでは、​​コールバックでuser等しいのではなく、次のようになります。{ foo: bar }{ uid: { foo: bar } }

これは重大な変更であるため、元のプロジェクトにプル リクエストを送信しませんでしたが、将来的にフラグやオプションを追加する場合に備えて、Issue に残しました。

于 2013-12-19T20:06:21.187 に答える