struct BSON

Overview

BSON is a binary format in which zero or more ordered key/value pairs are stored as a single entity.

BSON [bee · sahn], short for Bin­ary JSON, is a bin­ary-en­coded seri­al­iz­a­tion of JSON-like doc­u­ments. Like JSON, BSON sup­ports the em­bed­ding of doc­u­ments and ar­rays with­in oth­er doc­u­ments and ar­rays. BSON also con­tains ex­ten­sions that al­low rep­res­ent­a­tion of data types that are not part of the JSON spec. For ex­ample, BSON has a Date type and a BinData type.

See: http://bsonspec.org/

require "bson"

data = BSON.new({
  hello: "world",
  time:  Time.utc,
  name:  BSON.new({
    first_name: "John",
    last_name:  "Doe",
  }),
  fruits: ["Orange", "Banana"],
})

puts data.to_json
# => {"hello":"world","time":{"$date":"2020-05-18T07:32:13.621000000Z"},"name":{"first_name":"John","last_name":"Doe"},"fruits":["Orange","Banana"]}

Included Modules

Defined in:

bson.cr
bson/annotations.cr
bson/binary.cr
bson/code.cr
bson/dbpointer.cr
bson/decimal128.cr
bson/helpers/builder.cr
bson/helpers/decoder.cr
bson/helpers/types.cr
bson/keys.cr
bson/object_id.cr
bson/symbol.cr
bson/timestamp.cr
bson/undefined.cr

Constructors

Class Method Summary

Instance Method Summary

Constructor Detail

def self.new(data : Bytes | Nil = nil, validate? = false) #

Allocate a BSON instance from a byte array.

NOTE The byte array is cloned.

data = "160000000378000E0000000261000200000062000000".hexbytes
io = IO::Memory.new(data)
bson = BSON.new(io)
puts bson.to_json # => {"x":{"a":"b"}}

[View source]
def self.new(io : IO) #

Allocate a BSON instance from an IO

data = "160000000378000E0000000261000200000062000000".hexbytes
bson = BSON.new(data)
puts bson.to_json # => {"x":{"a":"b"}}

[View source]
def self.new(tuple : NamedTuple) #

Allocate a BSON instance from a NamedTuple.

puts BSON.new({
  hello: "world",
}).to_json # => {"hello":"world"}

[View source]
def self.new(h : Hash) #

Allocate a BSON instance from a Hash.

puts BSON.new({
  "hello" => "world",
}).to_json # => {"hello":"world"}

[View source]
def self.new(bson : BSON) #

No-op


[View source]
def self.new(ary : Array) #

Allocate a BSON instance from an Array.

puts BSON.new([1, 2, 3]).to_json # => [1,2,3]

[View source]
def self.new(serializable : BSON::Serializable) #

Allocate a BSON instance from an instance of BSON::Serializable.


[View source]

Class Method Detail

def self.from_json(json : String) #

Allocate a BSON instance from a relaxed extended json representation.

NOTE see https://github.com/mongodb/specifications/blob/master/source/extended-json.rst

bson = BSON.from_json(%({
  "_id": {
    "$oid": "57e193d7a9cc81b4027498b5"
  },
  "String": "string",
  "Int": 42,
  "Double": -1.0
}))
puts bson.to_json # => {"_id":{"$oid":"57e193d7a9cc81b4027498b5"},"String":"string","Int":42,"Double":-1.0}

[View source]

Instance Method Detail

def <=>(other : BSON) #

Compare with another BSON value.

puts BSON.new({a: 1}) <=> BSON.new({a: 1}) # => 0
puts BSON.new({a: 1}) <=> BSON.new({b: 2}) # => -1

[View source]
def [](key : String | ::Symbol) : Value #

Return the element with the given key.

NOTE Will raise if the key is not found.

bson = BSON.new({ key: "value" })
puts bson["key"] # =>"value"
puts bson["nope"] # => Unhandled exception: Missing bson key: nope (Exception)

[View source]
def []=(key : String | ::Symbol, value) #

Append a key/value pair.

bson = BSON.new
bson["key"] = "value"
puts bson.to_json # => {"key":"value"}

[View source]
def []?(key : String | ::Symbol) : Value | Nil #

Return the element with the given key, or nil if the key is not present.

bson = BSON.new({key: "value"})
puts bson["key"]?  # => "value"
puts bson["nope"]? # => nil

[View source]
def append(other : BSON) #

Append the contents of another BSON instance.

bson = BSON.new
other_bson = BSON.new({key: "value", key2: "value2"})
bson.append(other_bson)
puts bson.to_json # => {"key":"value","key2":"value2"}

[View source]
def append(**args) #

Append one or more key/value pairs.

NOTE more efficient for appending multiple values than calling #[]= individually.

bson = BSON.new
bson.append(key: "value", key2: "value2")
puts bson.to_json # => {"key":"value","key2":"value2"}

[View source]
def append_array(key : String | ::Symbol, value : BSON) #

Append a key/value pair and declare it as a BSON array.


[View source]
def clear #

Clears the BSON instance.


[View source]
def data : Slice(UInt8) #

Underlying bytes


[View source]
def dig(key : String | ::Symbol, *subkeys) #

Traverses the depth of a structure and returns the value, otherwise raises.


[View source]
def dig?(key : String | ::Symbol, *subkeys) #

Traverses the depth of a structure and returns the value. Returns nil if not found.


[View source]
def each(&block : Item -> _) #

Yield each key/value pair to the block.

NOTE Underlying BSON code as well as the binary subtype are also yielded to the block as additional arguments.

BSON.new({
  a: 1,
  b: "2",
  c: Slice[0_u8, 1_u8, 2_u8],
}).each { |(key, value, code, binary_subtype)|
  puts "#{key} => #{value}, code: #{code}, subtype: #{binary_subtype}"
# a => 1, code: Int32, subtype:
# b => 2, code: String, subtype:
# c => Bytes[0, 1, 2], code: Binary, subtype: Generic
}

[View source]
def each #

Returns an Iterator over each key/value pair.


[View source]
def empty? : Bool #

Returns true if the BSON is empty.


[View source]
def has_key?(key : String | ::Symbol) : Bool #

Returns true when key given by key exists, otherwise false.


[View source]
def size #

Return the size of the BSON instance in bytes.


[View source]
def to_canonical_extjson #

Serialize this BSON instance into a canonical extended json representation.

NOTE see https://github.com/mongodb/specifications/blob/master/source/extended-json.rst

bson = BSON.from_json(%({
  "Int": 42,
  "Double": -1.0
}))
puts bson.to_canonical_extjson # => {"Int":{"$numberLong":"42"},"Double":{"$numberDouble":"-1.0"}}

[View source]
def to_h #

Returns a Hash representation.

NOTE This function is recursive and will convert nested BSON to hash objects.

bson = BSON.new({
  a: 1,
  b: "2",
  c: {
    d: 1,
  },
})
pp bson.to_h # => {"a" => 1, "b" => "2", "c" => { "d" => 1}}

[View source]
def to_json(builder : JSON::Builder, *, array = false) #

ameba:disable Metrics/CyclomaticComplexity


[View source]
def validate! #

Validate that the BSON is well-formed.

bson = BSON.new("140000000461000D0000001030000A0000000000".hexbytes)
bson.validate!
# => Unhandled exception: Invalid BSON (overflow) (Exception)

[View source]