【问题标题】:Ruby pretty print a BSON document?Ruby 漂亮地打印一个 BSON 文档?
【发布时间】:2018-01-22 06:59:10
【问题描述】:

我正在使用 Ruby 在 MongoDB 中打印出 BSON 文档。这是使用 MongoDB 的 Ruby 包装器完成的。

  client[:test].find().each do |doc|
    puts doc.to_json()
  end

find 方法返回一个 BSON 文档。这可以使用to_json 方法将converted 转换为字符串。

输出如下:

{"_id":{"$oid":"5a64d2ce36ab1f1ea4b06228"},"admin":"1234","users":"12345","house":{"a":0,"b":0,"c":0},"room":{"a":0,"b":2,"c":1}}

输出不是很容易阅读。虽然我可以使用一些正则表达式魔法将上述字符串格式化为更易于理解的内容,但有没有一种更简单的方法可以以类似的格式很好地格式化 BSON 文档:

_id: #
"admin": "1234"
"users": "12345"
"house":
  "a": 1
  "b": 2

我尝试了以下StackOverflow 链接。但是,答案为attributes 产生了无方法错误,并且在将其替换为keys 之后仅打印keys,而不是values

【问题讨论】:

    标签: ruby mongodb bson


    【解决方案1】:

    虽然我以前没有使用过 mongodb 或 BSON,但如果我们从 JSON 的角度来处理这个问题,您有几个选择。首先,不是调用doc.to_json,而是使用方法as_json 来获取哈希表示,然后将其转换为字符串,因此我们将使用doc.as_json 作为起点。

    doc = {"_id":{"$oid":"5a64d2ce36ab1f1ea4b06228"},"admin":"1234","users":"12345","house":{"a":0,"b":0,"c":0},"room":{"a":0,"b":2,"c":1}}
    

    第一种方法是使用PP 库,它是一个漂亮的 ruby​​ 打印机:

    require 'pp'
    pp doc
    # Outputs:
    # {:_id=>{:$oid=>"5a64d2ce36ab1f1ea4b06228"},
    #  :admin=>"1234",
    #  :users=>"12345",
    #  :house=>{:a=>0, :b=>0, :c=>0},
    #  :room=>{:a=>0, :b=>2, :c=>1}}
    

    这与您想要的很接近,pp 库有一种方法可以通过在您的类中定义一个 #pretty_print(pp) 函数来定义自定义输出,您可以使用它来帮助完成剩下的工作。

    要查看的第二个选项是JSON.pretty_generate

    require 'json'
    puts JSON.pretty_generate(doc)
    # {
    #   "_id": {
    #     "$oid": "5a64d2ce36ab1f1ea4b06228"
    #   },
    #   "admin": "1234",
    #   "users": "12345",
    #   "house": {
    #     "a": 0,
    #     "b": 0,
    #     "c": 0
    #   },
    #   "room": {
    #     "a": 0,
    #     "b": 2,
    #     "c": 1
    #   }
    # }
    

    这更接近你想要的。如果需要,通过一些后期处理,您可以去掉那些括号和逗号:

    puts JSON.pretty_generate(doc).delete('{},').gsub(/\n\s*\n/, "\n")
    

    至于为什么从attributes 切换到keys 开始只输出keys,好吧attributes 看起来和听起来像是一个哈希,因此循环通过你有2 个元素被传递到每个块时间,keys 听起来像一个数组,所以你只能得到属性的名称。如前所述,我不知道 mongo,但是您需要以某种方式使用模型上命名的键查找属性以获得它的值。例如在 ActiveRecord 中,如果您无法使用 attributes 方法,则可以使用 public_send(key)

    【讨论】:

      【解决方案2】:

      使用真棒打印

      将 BSON 转换为 Ruby 哈希后,您有很多选择。其中之一是使用Awesome Print gem 来漂亮地打印带有各种可配置选项的哈希对象。例如:

      require 'awesome_print'
      
      hash = {:_id=>{:$oid=>"5a64d2ce36ab1f1ea4b06228"},
              :admin=>"1234",
              :users=>"12345",
              :house=>{:a=>0, :b=>0, :c=>0},
              :room=>{:a=>0, :b=>2, :c=>1}}
      ap h, indent: 2, index: false
      
      {
          :_id => {
          :$oid => "5a64d2ce36ab1f1ea4b06228"
        },
        :admin => "1234",
        :users => "12345",
        :house => {
          :a => 0,
          :b => 0,
          :c => 0
        },
         :room => {
          :a => 0,
          :b => 2,
          :c => 1
        }
      }
      

      另请注意,用于漂亮打印的PP classautomatically loaded in Ruby 2.5.0。在某些情况下,pp some_hash 可能就是您所需要的。 YMMV。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-05-08
        • 1970-01-01
        • 2011-09-29
        • 2017-08-13
        • 1970-01-01
        • 2011-01-07
        • 1970-01-01
        • 2012-10-08
        相关资源
        最近更新 更多