【问题标题】:Force mongodb to output strict JSON强制 mongodb 输出严格的 JSON
【发布时间】:2015-11-12 20:29:34
【问题描述】:

我想在其他说 JSON 的程序中使用一些 MongoDB 命令的原始输出。当我在 mongo shell 中运行命令时,它们代表 Extended JSON,“shell 模式”中的字段,以及 NumberLongDateTimestamp 等特殊字段。我在文档中看到对“严格模式”的引用,但我看不到为 shell 打开它的方法,或者在 do 输出严格 JSON 的事情中运行像 db.serverStatus() 这样的命令的方法,喜欢mongodump。如何强制 Mongo 输出符合标准的 JSON?

关于这个话题有severalotherquestions,但我觉得他们的回答都不是特别令人满意。

【问题讨论】:

  • 你搞错了。 shell 使用“严格”语法,即 { "a": NumberLong(1) } 等。而 shell 根本不支持的“扩展 JSON”被 mongoexport 之类的工具使用,"a":{"$numberLong":"1"}} 是可解析的 JSON 形式。 mongodump 只是转储 BSON 数据文件。
  • 你错了。 documentation 清楚地表明 NumberLong 类型的“严格模式”表示为{ "$numberLong": "<number>" },而“shell 模式”表示为NumberLong( "<number>" )。我可以编辑问题以阐明“扩展 JSON”和“shell 模式”之间的区别。
  • 就像我说的。你完全相反。扩展 JSON 就是您所说的“严格”。
  • 语义并没有真正改变问题或答案,但 FWIW,先前链接的文档指定“shell 模式”和“严格模式”都是 JSON 的扩展,因此“扩展 JSON”包括两者。如果有其他文件表明不是这样,我很想看看。
  • 布莱克七请阅读 docs.mongoing.com/manual/reference/mongodb-extended-json.html 严格模式 -> { "$oid": "" } shell 模式 -> ObjectId( "" ) strict = 标准 Json

标签: json mongodb shell bson


【解决方案1】:

MongoDB shell 使用 Javascript,所以答案很简单:使用 JSON.stringify()。如果你的命令是db.serverStatus(),那么你可以这样做:

JSON.stringify(db.serverStatus())

这不会输出每个字段的正确“严格模式”表示({ "floatApprox": <number> } 而不是{ "$numberLong": "<number>" }),但如果您关心的是获得符合标准的 JSON,这将完成把戏。

【讨论】:

  • 这也是错误的。因为JSON.stringify({ "a": NumberLong(1) }){"a":{"floatApprox":1}} 出现,这完全不是Extended JSON 格式。我认为在您寻求更多自我答案之前,您应该多研究一下材料。
  • 问题的症结在于如何让 shell 吐出可以被符合标准的 JSON 解析器解析的内容。这实现了这个目标。不过,我将编辑答案以澄清这一点。
  • 您能提出改进建议吗?
  • 如果我们也能得到“强制 mongodb 输出扩展 JSON”的答案,那就太好了……但这不是你要问的
  • 你摇滚。你让我今天一整天都感觉很好!谢谢!!
【解决方案2】:

我还没有找到在 mongo shell 中执行此操作的方法,但作为一种解决方法,mongoexport 可以运行查询,其输出使用严格模式,并且可以通过管道传输到其他需要 JSON 输入的命令(例如 @987654322 @ 或 jq)。例如,假设您有以下 mongo shell 命令来运行查询,并且您想使用该数据创建管道:

db.myItemsCollection.find({creationDate: {$gte: ISODate("2016-09-29")}}).pretty()

将该 mongo shell 命令转换为该 shell 命令,以管道为例,以 `json_pp:

mongoexport --jsonArray -d myDbName -c myItemsCollection -q '{"creationDate": {"$gte": {"$date": "2016-09-29T00:00Z"}}}' | json_pp

您需要将查询转换为严格模式格式,并将数据库名称和集合名称作为参数传递,并为您的 shell 正确引用,如下所示。

【讨论】:

  • 不知道这个!我只希望它支持聚合。
【解决方案3】:

要以@jbyler 的答案为基础,您可以在获取数据后使用sed 去除 numberLongs - 如果您使用的是 linux。

mongoexport --jsonArray -d dbName -c collection -q '{fieldName: {$regex: ".*turkey.*"}}' | sed -r 's/\{ "[$]numberLong" : "([0-9]+)" }/"\1"/g' | json_pp

【讨论】:

    【解决方案4】:

    编辑:这将转换给定的文档,但不适用于文档列表。将find 更改为findOne

    添加

    .forEach(function(results){results._id=results._id.toString();printjson(results)})`
    

    findOne() 将输出有效的 JSON。

    例子:

    db
      .users
      .findOne()
      .forEach(function (results) {
        results._id = results._id.toString();
        printjson(results)
      })
    

    来源:https://www.mydbaworld.com/mongodb-shell-output-valid-json/

    【讨论】:

    • 不够通用。我有一个很大的文档,我很难自己处理每个字段。
    【解决方案5】:

    如果是 findOne

    JSON.stringify(db.Bill.findOne({'a': '123'}))
    

    如果是光标

    db.Bill.find({'a': '123'}).forEach(r=>print(JSON.stringify(r)))
    

    print('[') + db.Bill.find().limit(2).forEach(r=>print(JSON.stringify(r) + ',')) + print(']')
    

    会输出

    [{a:123},{a:234},]
    

    最后一项将在最后一项之后有一个“,”...删除它

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-30
      • 1970-01-01
      • 2011-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-11
      • 2011-07-29
      相关资源
      最近更新 更多