一尘不染

如何使用Python将MongoDB的bsondump转换为JSON?

json

因此,我在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-垃圾邮件检测可防止第三个链接),该输出似乎与上述转储输出相同。加载给出错误:

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

那么,如何将TenGen JSON的字符串转换为可解析的JSON?(最终目标是将制表符分隔的数据流传输到另一个数据库)


阅读 530

收藏
2020-07-27

共1个答案

一尘不染

您所拥有的是TenGen模式下的Mongo Extended
JSON中的转储(请参阅此处)。一些可行的方法:

  1. 如果可以再次转储,请通过MongoDB REST API使用严格输出模式。那应该给您真正的JSON,而不是现在的JSON。

  2. 使用bsonhttp://pypi.python.org/pypi/bson/读你已经有了BSON到Python的数据结构,然后做任何处理,你需要对这些(可能输出JSON)。

  3. 使用MongoDB Python绑定连接到数据库以将数据导入Python,然后进行所需的任何处理。(如果需要,您可以设置本地MongoDB实例,然后将转储的文件导入该实例。)

  4. 将Mongo Extended 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))

根据您的目标,其中一个应该是一个合理的起点。

2020-07-27