0

新しい形式にマップして新しい DB にアップロードする必要がある非常に大きな (> 500MB) JSON ファイルがいくつかあります。

古い形式:

{
    id: '001',
    timestamp: 2016-06-02T14:10:53Z,
    contentLength: 123456,
    filepath: 'original/...',
    size: 'original'
},
{
    id: '001',
    timestamp: 2016-06-02T14:10:53Z,
    contentLength: 24565,
    filepath: 'medium/...',
    size: 'medium'
},
{
    id: '001',
    timestamp: 2016-06-02T14:10:53Z,
    contentLength: 5464,
    filepath: 'small/...',
    size: 'small'
}

新しいフォーマット:

{
    Id: '001',
    Timestamp: 2016-06-02T14:10:53Z,
    OriginalSize: {
        ContentLength: 123456,
        FilePath: 'original/...'
    },
    MediumSize: {
       ContentLength: 24565,
       FilePath: 'medium/...'
    },
    SmallSize: {
        ContentLength: 5464,
        FilePath: 'small/...'
    }
}

最初に「元の」サイズを処理して、このような小さなデータセットでこれを達成していました:

let out = data.filter(o => o.size === 'original).map(o => {
    return {
        Id: o.id,
        Timestamp: o.timestamp,
        OriginalSize: {
            ContentLength: o.contentLength,
            FilePath: o.filepath
        }
    };
});
data.filter(o => o.size !== 'original').forEach(o => {
    let orig = out.find(function (og) {
        return og.Timestamp === o.timestamp;
    });
    orig[o.size + 'Size'] = {
        ContentLength: o.contentLength,
        FilePath: o.filepath
    };
)
// out now contains the correctly-formatted objects

問題は非常に大きなデータセットにあり、数百メガバイトの JSON を一度にメモリにロードすることはできません。これはストリームを使用する絶好の機会のように思えますが、もちろん、ファイルをチャンクで読み取る場合、小さな配列で .find() を実行して「元の」サイズを見つけることはできません。ファイル全体をスキャンしてオリジナルを見つけ、もう一度スキャンして見つかったものに他のサイズを追加すると、とにかくデータセット全体がメモリに保存されます。

オブジェクトの単純な 1 対 1 の再マッピングを行っていた場合、これは素晴らしいことです

確かに、この種の問題に遭遇するのは私が最初ではありません。過去にどのようなソリューションが使用されましたか? どうすればこれにアプローチできますか?

4

2 に答える 2

0

JSON ドキュメントを保存できる DB インスタンスをセットアップします。MongoDB または PostgreSQL (最近、json ドキュメントを格納するための jsonb データ型が導入されました)。DB をストレージとして使用して、古い JSON ドキュメントを反復処理し、それらを新しい構造に結合して、メモリの問題を解決します。

a)プロセスの速度を(劇的に)犠牲にするか、b)貧乏人のDBをゼロから作成する(これは悪いことのようです:))

于 2016-06-02T15:19:34.570 に答える