Class: BSON::Document

Inherits:
Hash
  • Object
show all
Defined in:
lib/bson/document.rb

Overview

Note:

The specification is: document ::= int32 e_list “x00”

This module provides behaviour for serializing and deserializing entire BSON documents, according to the BSON specification.

See Also:

Since:

  • 2.0.0

Direct Known Subclasses

DBRef

Instance Method Summary collapse

Constructor Details

#initialize(elements = nil) ⇒ Document

Instantiate a new Document. Valid parameters for instantiation is a hash only or nothing.

Examples:

Create the new Document.

BSON::Document.new(name: "Joe", age: 33)

Parameters:

  • elements (Hash) (defaults to: nil)

    The elements of the document.

Since:

  • 3.0.0



213
214
215
216
# File 'lib/bson/document.rb', line 213

def initialize(elements = nil)
  super()
  (elements || {}).each_pair{ |key, value| self[key] = value }
end

Instance Method Details

#[](key) ⇒ Object

Get a value from the document for the provided key. Can use string or symbol access, with string access being the faster of the two.

Examples:

Get an element for the key.

document["field"]

Get an element for the key by symbol.

document[:field]

Parameters:

Returns:

  • (Object)

    The found value, or nil if none found.

Since:

  • 2.0.0



89
90
91
# File 'lib/bson/document.rb', line 89

def [](key)
  super(convert_key(key))
end

#[]=(key, value) ⇒ Object

Stores a key-value pair in the current document.

Since BSON documents provide deep indifferent access (both strings and symbols are accepted as keys, recursively), the value may be converted to facilitate indifferent access. This conversion is performed for built-in Array and Hash classes, and other classes can override to_bson_normalized_value method to provide custom conversion logic. For example:

doc = BSON::Document.new
doc[:a] = {b: {c: 'd'}}
doc['a']['b']['c']
# => "d"

Note that due to this conversion, the object that is stored in the receiver Document may be different from the object supplied as the right hand side of the assignment. In Ruby, the result of assignment is the right hand side, not the return value of []= method. Because of this, modifying the result of assignment generally does not work as intended:

doc = BSON::Document.new
foo = (doc[:a] = {b: {c: 'd'}})
# foo is original Hash with symbol keys
foo['test'] = 'test'
# doc is not modified
doc
# => {"a"=>{"b"=>{"c"=>"d"}}}

This behavior can be encountered when defaulting document contents with []= in a method, such as:

def foo
  # @doc is a BSON::Document
  @doc[:foo] ||= calculation
end

The above method should be written as follows to allow chaining:

def foo
  # @doc is a BSON::Document
  @doc[:foo] ||= calculation and @doc[:foo]
end

Examples:

Set a value on the document.

document[:test] = "value"

Parameters:

Returns:

  • (Object)

    The updated value.

Since:

  • 3.0.0



146
147
148
# File 'lib/bson/document.rb', line 146

def []=(key, value)
  super(convert_key(key), convert_value(value))
end

#delete(key, &block) ⇒ Object

Deletes the key-value pair and returns the value from the document whose key is equal to key. If the key is not found, returns the default value. If the optional code block is given and the key is not found, pass in the key and return the result of block.

Examples:

Delete a key-value pair

document.delete(:test)

Parameters:

  • key (Object)

    The key of the key-value pair to delete.

Returns:

Since:

  • 4.0.0



200
201
202
# File 'lib/bson/document.rb', line 200

def delete(key, &block)
  super(convert_key(key), &block)
end

#dig(*keys) ⇒ Object, NilClass

Retrieves the value object corresponding to the each key objects repeatedly. Will normalize symbol keys into strings.

Examples:

Get value from nested sub-documents, handling missing levels.

document # => { :key1 => { "key2" => "value"}}
document.dig(:key1, :key2) # => "value"
document.dig("key1", "key2") # => "value"
document.dig("foo", "key2") # => nil

Parameters:

  • *keys (Array<String, Symbol>)

    Keys, which constitute a “path” to the nested value.

Returns:

Since:

  • 3.0.0



269
270
271
# File 'lib/bson/document.rb', line 269

def dig(*keys)
  super(*keys.map{|key| convert_key(key)})
end

#except(*keys) ⇒ BSON::Document

Note:

This method is always defined, even if Hash already contains a definition of #except, because ActiveSupport unconditionally defines its version of #except which doesn’t work for BSON::Document which causes problems if ActiveSupport is loaded after bson-ruby is.

Returns a new document consisting of the current document minus the specified keys.

The keys to be removed can be specified as either strings or symbols.

Examples:

Get a document/hash with only the ‘name` and `age` fields removed

document # => { _id: <ObjectId>, :name => 'John', :age => 30, :location => 'Earth' }
document.except(:name, 'age') # => { _id: <ObjectId>, location: 'Earth' }

Parameters:

  • *keys (Array<String, Symbol>)

    Keys, that will be removed in the resulting document

Returns:

Since:

  • 2.0.0



314
315
316
317
318
# File 'lib/bson/document.rb', line 314

def except(*keys)
  copy = dup
  keys.each {|key| copy.delete(key)}
  copy
end

#fetch(key) ⇒ Object #fetch(key, default) ⇒ Object #fetch(key, &block) ⇒ Object

Get a value from the document for the provided key. Can use string or symbol access, with string access being the faster of the two.

Examples:

Get an element for the key.

document.fetch("field")

Get an element for the key by symbol with a default.

document.fetch(:field, 'foo')

Get an element for the key by symbol with a block default.

document.fetch(:field) { |key| key.upcase }

Overloads:

  • #fetch(key) ⇒ Object

    Returns a value from the hash for the given key. If the key does not exist, raises KeyError exception.

  • #fetch(key, default) ⇒ Object

    Returns a value from the hash for the given key. If the key does not exist, returns default.

  • #fetch(key, &block) ⇒ Object

    Returns a value from the hash for the given key. If the key does not exist, returns the value of the block called with the key.

Parameters:

  • key (String, Symbol)

    The key to look up.

  • default (Object)

    Returned value if key does not exist.

Yields:

  • (key)

    Block returning default value for the given key.

Returns:

  • (Object)

    The found value. Raises KeyError if none found.

Since:

  • 4.4.0



70
71
72
73
# File 'lib/bson/document.rb', line 70

def fetch(key, *args, &block)
  key = convert_key(key)
  super(key, *args, &block)
end

#has_key?(key) ⇒ true, false Also known as: include?, key?, member?

Returns true if the given key is present in the document. Will normalize symbol keys into strings.

Examples:

Test if a key exists using a symbol

document.has_key?(:test)

Parameters:

  • key (Object)

    The key to check for.

Returns:

  • (true, false)

Since:

  • 4.0.0



161
162
163
# File 'lib/bson/document.rb', line 161

def has_key?(key)
  super(convert_key(key))
end

#has_value?(value) ⇒ true, false Also known as: value

Returns true if the given value is present in the document. Will normalize symbols into strings.

Examples:

Test if a key exists using a symbol

document.has_value?(:test)

Parameters:

  • value (Object)

    THe value to check for.

Returns:

  • (true, false)

Since:

  • 4.0.0



180
181
182
# File 'lib/bson/document.rb', line 180

def has_value?(value)
  super(convert_value(value))
end

#merge(other, &block) ⇒ BSON::Document

Merge this document with another document, returning a new document in the process.

Examples:

Merge with another document.

document.merge(name: "Bob")

Parameters:

Returns:

Since:

  • 3.0.0



229
230
231
# File 'lib/bson/document.rb', line 229

def merge(other, &block)
  dup.merge!(other, &block)
end

#merge!(other) ⇒ BSON::Document Also known as: update

Merge this document with another document, returning the same document in the process.

Examples:

Merge with another document.

document.merge(name: "Bob")

Parameters:

Returns:

Since:

  • 3.0.0



244
245
246
247
248
249
250
# File 'lib/bson/document.rb', line 244

def merge!(other)
  other.each_pair do |key, value|
    value = yield(convert_key(key), self[key], convert_value(value)) if block_given? && self[key]
    self[key] = value
  end
  self
end

#slice(*keys) ⇒ BSON::Document

Slices a document to include only the given keys. Will normalize symbol keys into strings. (this method is backported from ActiveSupport::Hash)

Examples:

Get a document/hash with only the ‘name` and `age` fields present

document # => { _id: <ObjectId>, :name => "John", :age => 30, :location => "Earth" }
document.slice(:name, 'age') # => { "name": "John", "age" => 30 }
document.slice('name') # => { "name" => "John" }
document.slice(:foo) # => {}

Parameters:

  • *keys (Array<String, Symbol>)

    Keys, that will be kept in the resulting document

Returns:

Since:

  • 4.3.1



289
290
291
292
293
294
295
# File 'lib/bson/document.rb', line 289

def slice(*keys)
  keys.each_with_object(self.class.new) do |key, hash|
    if key?(key)
      hash[key] = self[key]
    end
  end
end

#symbolize_keys!Object

Raises:

  • (ArgumentError)

Since:

  • 2.0.0



320
321
322
# File 'lib/bson/document.rb', line 320

def symbolize_keys!
  raise ArgumentError, 'symbolize_keys! is not supported on BSON::Document instances. Please convert the document to hash first (using #to_h), then call #symbolize_keys! on the Hash instance'
end

#to_bson_normalized_valueBSON::Document

Override the Hash implementation of to_bson_normalized_value.

BSON::Document is already of the correct type and already provides indifferent access to keys, hence no further conversions are necessary.

Attempting to perform Hash’s conversion on Document instances converts DBRefs to Documents which is wrong.

Returns:

Since:

  • 2.0.0



333
334
335
# File 'lib/bson/document.rb', line 333

def to_bson_normalized_value
  self
end