web-dev-qa-db-ja.com

ストリーミングjsonパーサー

私は、メモリにロードできない非常に大きなJSONファイル(〜1TB)のストリーミングjsonパーサーを実装しようとしています。 1つのオプションは、ファイルをjson-newline-delimitedに変換するために https://github.com/stedolan/jq のようなものを使用することですが、各jsonオブジェクトに対して実行する必要がある他のさまざまな処理がありますこのため、このアプローチは理想的ではありません。

非常に大きなjsonオブジェクトがある場合、xmlでのこのアプローチと同様に、オブジェクトごとにどのように解析できますか: https://www.ibm.com/developerworks/library/x-hiperfparse/ index.html

たとえば、疑似コードでは:

with open('file.json','r') as f:
    json_str = ''
    for line in f: # what if there are no newline in the json obj?
        json_str += line
        if is_valid(json_str):
            obj = json.loads(json_str)
            do_something()
            json_str = ''

さらに、jq -cが特に高速であるとは思いませんでした(メモリに関する考慮事項を無視)。たとえば、json.loadsを使用するのは、jq -cを使用する場合と同じくらい高速でした(そして少し高速でした)。 ujsonも使用してみましたが、ファイルサイズに関連すると思われる破損エラーが発生し続けました。

# file size is 2.2GB
>>> import json,time
>>> t0=time.time();_=json.loads(open('20190201_iTunes.txt').read());print (time.time()-t0)
65.6147990227

$ time cat 20190206_iTunes.txt|jq -c '.[]' > new.json
real    1m35.538s
user    1m25.109s
sys 0m15.205s

最後に、テストに使用できる100KB json入力の例を次に示します。 https://hastebin.com/ecahufonet.json

7
user10332687

このjsonをファイルシステムツリー(フォルダーとファイル)に変換することを検討してください。これにより、すべてのjsonオブジェクトがファイルを含むフォルダーに変換されます。

  • name.txt-親フォルダー(json-object)内のプロパティの名前が含まれ、プロパティの値は現在のフォルダー(json-object)です
  • properties_000000001.txt
  • properties_000000002.txt

    ....

すべてのproperties_X.txtファイルには、最大でN(制限された数)行が含まれますproperty_name: property_value

  • "number_property":100
  • "boolean_property":true
  • 「object_property」:フォルダー(folder_0000001)
  • 「array_property」:フォルダー(folder_000002)

folder_0000001、folder_000002-ローカルフォルダーの名前

すべての配列はファイルを含むフォルダーに変換されます。

  • name.txt
  • elements_0000000001.txt
  • elements_0000000002.txt

    ....

0
jnr