所以我有大量的.来自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呢?

推荐答案

您拥有的是TenGen模式下的Mongo扩展JSON转储(参见here).一些可能的方法:

  1. 如果可以再次转储,请通过MongoDB REST API使用严格的输出模式.这会给你真正的JSON,而不是你现在拥有的.

  2. 使用bson from http://pypi.python.org/pypi/bson/将您已有的BSON读入Python数据 struct ,然后对这些数据 struct 执行您需要的任何处理(可能输出JSON).

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

  4. 将Mongo扩展JSON从TenGen模式转换为Strict模式.您可以开发一个单独的过滤器来完成这项工作(从stdin读取,用严格的 struct 替换TenGen struct ,并在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))

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

Mongodb相关问答推荐

如何拉平mongo DB中的对象并在根目录中保存时有条件地重命名字段?

在MongoDB查询中添加来自另一个集合的匹配文档的计数

Mongo聚合项目数组交集

MongoDB:检测所有重叠事件(开始/结束日期)?

避免在 MongoDB 聚合框架中使用 ISODate() 以便管道可以是纯 JSON

如何在 go mongo-driver 中为 options.FindOne() 设置限制

根据条件删除一些数组元素并将数组的大小更新为mongo中的另一个文件

使用golang的MongoDB错误无法访问服务器

用Golang减go mongodb中的两个字段

为什么一个 mongodb 副本集需要奇数个投票 node ?

mongo _id 字段重复键错误

如何在mongo中插入带有日期的文档?

为什么 PyMongo 会抛出 AutoReconnect?

Mongodb 类型引用 node

查询 Mongoid/rails 3 中的嵌入对象(Lower than、Min 运算符和排序)

初创公司应该考虑哪些数据库系统?

如何在第一个文档中恢复 MongoDB ChangeStream 而不仅仅是在我开始收听后更改

在 mongoose 中使用 UUID 进行 ObjectID 引用

mongo中的稀疏索引和空值

即使重新安装后,Mongo 仍在等待 27017