I am using Ruby to print out a BSON document in MongoDB. This is done using a Ruby wrapper for MongoDB.
client[:test].find().each do |doc|
puts doc.to_json()
end
The find method returns a BSON document. This can be converted to a string using the to_json
method.
The output which looks like this:
{"_id":{"$oid":"5a64d2ce36ab1f1ea4b06228"},"admin":"1234","users":"12345","house":{"a":0,"b":0,"c":0},"room":{"a":0,"b":2,"c":1}}
The output is not very human readable. While I could possibly use some regex magic to format the above string to something more comprehensible, is there an easier way to format a BSON document nicely in a similar format as below:
_id: #
"admin": "1234"
"users": "12345"
"house":
"a": 1
"b": 2
I have tried the following StackOverflow link. However, the answer yields a no method error for attributes
and following the replacing that with keys
following the comment only prints keys, not values.
While I haven't used mongodb or BSON before, if we approach this from a JSON perspective you have a couple options. First, instead of calling doc.to_json
, it looks like that uses a method as_json
to get a hash representation, that it then turns into a string, so we'll use doc.as_json
as a starting point instead.
doc = {"_id":{"$oid":"5a64d2ce36ab1f1ea4b06228"},"admin":"1234","users":"12345","house":{"a":0,"b":0,"c":0},"room":{"a":0,"b":2,"c":1}}
The first way is to use the PP
library which is a pretty printer for 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}}
which is close to what you want, the pp
library has a way to define a customized output by defining a #pretty_print(pp)
function in your class, that you can use to help get it the rest of the way.
The second option to look into is 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
# }
# }
Which is a bit closer to what you're wanting. With some post-processing you can get rid of those brackets and commas, if you want:
puts JSON.pretty_generate(doc).delete('{},').gsub(/\n\s*\n/, "\n")
As for why switching from attributes
to keys
starts outputting only the keys
, well attributes
looks and sounds like it would be a hash, thus looping through you have 2 elements being passed to the block each time, and keys
sounds like an array, so you only get the name of the attribute. As mentioned, I don't know mongo, but you would then need to somehow look up the attribute with the key named on your model to get it's value. For instance in ActiveRecord, you might use a public_send(key)
if you weren't able to use its attributes
method.