24

そのため、MongoDB ダンプから膨大な量の .bson があります。コマンドラインでbsondumpを使用して、出力を stdin として python にパイプします。これは BSON から 'JSON' に正常に変換されますが、実際には文字列であり、正当な JSON ではないようです。

たとえば、着信行は次のようになります。

{ "_id" : ObjectId( "4d9b642b832a4c4fb2000000" ),
  "acted_at" : Date( 1302014955933 ),
  "created_at" : Date( 1302014955933 ),
  "updated_at" : Date( 1302014955933 ),
  "_platform_id" : 3,
  "guid" : 72106535190265857 }

私が信じているのはMongo Extended JSONです。

そのような行を読んで実行すると:

json_line = json.dumps(line)

私は得る:

"{ \"_id\" : ObjectId( \"4d9b642b832a4c4fb2000000\" ),
\"acted_at\" : Date( 1302014955933 ),
\"created_at\" : Date( 1302014955933 ),
\"updated_at\" : Date( 1302014955933 ),
\"_platform_id\" : 3,
\"guid\" : 72106535190265857 }\n"

まだ<type 'str'>です。

私も試してみました

json_line = json.dumps(line, default=json_util.default)

(pymongo json_util - spam detection prevent a third link を参照) 上記のダンプと同じように出力されるようです。ロードするとエラーが発生します:

json_line = json.loads(line, object_hook=json_util.object_hook)
ValueError: No JSON object could be decoded

では、TenGen JSON の文字列を解析可能な JSON に変換するにはどうすればよいでしょうか? (最終的な目標は、タブで区切られたデータを別のデータベースにストリーミングすることです)

4

4 に答える 4

18

持っているのは、TenGenモードのMongo拡張JSONでのダンプです(ここを参照)。いくつかの可能な方法:

  1. 再度ダンプできる場合は、MongoDBRESTAPIを介して厳密な出力モードを使用してください。これにより、現在のJSONではなく実際のJSONが得られるはずです。

  2. http://pypi.python.org/pypi/bson/から使用bsonして、既に持っているBSONをPythonデータ構造に読み込み、それらに対して必要な処理を実行します(JSONを出力する可能性があります)。

  3. MongoDB Pythonバインディングを使用してデータベースに接続し、データをPythonに取り込み、必要な処理を実行します。(必要に応じて、ローカルのMongoDBインスタンスをセットアップし、ダンプされたファイルをそのインスタンスにインポートできます。)

  4. Mongo拡張JSONをTenGenモードからStrictモードに変換します。それを行うために別のフィルターを開発するか(stdinから読み取り、TenGen構造をStrict構造に置き換え、結果をstdoutに出力する)、または入力を処理するときにそれを行うことができます。

Pythonと正規表現を使用した例を次に示します。

import json, re
from bson import json_util

with open("data.tengenjson", "rb") as f:
    # read the entire input; in a real application,
    # you would want to read a chunk at a time
    bsondata = f.read()

    # convert the TenGen JSON to Strict JSON
    # here, I just convert the ObjectId and Date structures,
    # but it's easy to extend to cover all structures listed at
    # http://www.mongodb.org/display/DOCS/Mongo+Extended+JSON
    jsondata = re.sub(r'ObjectId\s*\(\s*\"(\S+)\"\s*\)',
                      r'{"$oid": "\1"}',
                      bsondata)
    jsondata = re.sub(r'Date\s*\(\s*(\S+)\s*\)',
                      r'{"$date": \1}',
                      jsondata)

    # now we can parse this as JSON, and use MongoDB's object_hook
    # function to get rich Python data structures inside a dictionary
    data = json.loads(jsondata, object_hook=json_util.object_hook)

    # just print the output for demonstration, along with the type
    print(data)
    print(type(data))

    # serialise to JSON and print
    print(json_util.dumps(data))

目標に応じて、これらの1つが妥当な出発点になるはずです。

于 2012-08-09T15:11:14.027 に答える
7

次のように bson ファイルの行を変換できます。

>>> import bson
>>> bs = open('file.bson', 'rb').read()
>>> for valid_dict in bson.decode_all( bs ):
....

各 valid_dict 要素は、json に変換できる有効な python dict になります。

于 2012-08-09T15:34:43.303 に答える
0

データ型を取り除き、正規表現を使用して厳密な json を取得できます。

import json
import re

#This will outputs a iterator that converts each file line into a dict.
def readBsonFile(filename):
    with open(filename, "r") as data_in:
        for line in data_in:
            # convert the TenGen JSON to Strict JSON
            jsondata = re.sub(r'\:\s*\S+\s*\(\s*(\S+)\s*\)',
                              r':\1',
                              line)

            # parse as JSON
            line_out = json.loads(jsondata)

            yield line_out
于 2019-07-04T14:11:51.457 に答える