Navigation
This version of the documentation is archived and no longer supported.

Upgrading Mongoid

This page describes significant changes and improvements in Mongoid releases. The complete list of releases is available on GitHub and in JIRA; please consult GitHub releases for detailed release notes and JIRA for the complete list of issues fixed in each release, including bug fixes.

Upgrading to Mongoid 7.1

The following sections describe significant changes in Mongoid 7.1.

Condition Combination

Breaking change: In Mongoid 7.1, when condition methods are invoked on a Criteria object, they always add new conditions to the existing conditions in the Criteria object. Previously new conditions could have replaced existing conditions in some circumstances.

Example Mongoid 7.1 behavior:

Band.where(id: 1).where(id: 2)
# => #<Mongoid::Criteria
#   selector: {"_id"=>1, "$and"=>[{"_id"=>2}]}
#   options:  {}
#   class:    Band
#   embedded: false>

Corresponding Mongoid 7.0 behavior:

Band.where(id: 1).where(id: 2)
# => #<Mongoid::Criteria
#   selector: {"_id"=>2}
#   options:  {}
#   class:    Band
#   embedded: false>

Known issue: When using Ruby 2.6 and lower, when adding multiple conditions on the same field using the same operator, the operator must be given as a string, not as a symbol. The following invocations fail:

Band.and({year: {'$in': [2020]}}, {year: {'$in': [2020]}})
# Traceback (most recent call last):
#         2: from (irb):10
#         1: from (irb):10:in `rescue in irb_binding'
# NoMethodError (undefined method `start_with?' for :$in:Symbol)

Band.and(year: {'$in': [2020]}).and(year: {'$in': [2020]})
# Traceback (most recent call last):
#         2: from (irb):11
#         1: from (irb):11:in `rescue in irb_binding'
# NoMethodError (undefined method `start_with?' for :$in:Symbol)

Use string keys instead:

# Band.and({year: {'$in' => [2020]}}, {year: {'$in' => [2020]}})
# => #<Mongoid::Criteria
#   selector: {"year"=>{"$in"=>[2020]}, "$and"=>[{"year"=>{"$in"=>[2020]}}]}
#   options:  {}
#   class:    Band
#   embedded: false>

Band.and(year: {'$in' => [2020]}).and(year: {'$in' => [2020]})
# => #<Mongoid::Criteria
#   selector: {"year"=>{"$in"=>[2020]}, "$and"=>[{"year"=>{"$in"=>[2020]}}]}
#   options:  {}
#   class:    Band
#   embedded: false>

This issue is rectified in Mongoid 7.3.

Logical Operations

Breaking change: In Mongoid 7.1 logical operator methods or and nor treat the receiver as one of the operands. This behavior matches that of ActiveRecord. Previously, or and nor added their parameters as additional conditions to the receiver.

Example Mongoid 7.1 behavior:

Band.where(name: 'One').or(name: 'Two')
# => #<Mongoid::Criteria
#   selector: {"$or"=>[{"name"=>"One"}, {"name"=>"Two"}]}
#   options:  {}
#   class:    Band
#   embedded: false>

Corresponding Mongoid 7.0 behavior:

Band.where(name: 'One').or(name: 'Two')
# => #<Mongoid::Criteria
#   selector: {"name"=>"One", "$or"=>[{"name"=>"Two"}]}
#   options:  {}
#   class:    Band
#   embedded: false>

To add or or nor parameters to the existing query without disjuncting the existing query, create a separate scope:

Band.where(name: 'One').and(Band.or({name: 'Two'}, {name: 'Three'}))
# => #<Mongoid::Criteria
#   selector: {"name"=>"One", "$and"=>[{"$or"=>[{"name"=>"Two"}, {"name"=>"Three"}]}]}
#   options:  {}
#   class:    Band
#   embedded: false>

Alternatively, use any_of which behaves as or did in Mongoid 7.0:

Band.where(name: 'One').any_of({name: 'Two'}, {name: 'Three'})
# => #<Mongoid::Criteria
#   selector: {"name"=>"One", "$or"=>[{"name"=>"Two"}, {"name"=>"Three"}]}
#   options:  {}
#   class:    Band
#   embedded: false>

For more information, please review the logical operations section of the documentation.

Merge Strategies

Breaking change: In Mongoid 7.1, Merge strategies must be explicitly requested. Previously, all defaulted to the union strategy and in and nin defaulted to the intersect strategy. In Mongoid 7.1, there is no merge strategy applied by default.

Example Mongoid 7.1 behavior:

Band.all(a: 1).all(a: 2)
# => #<Mongoid::Criteria
#   selector: {"a"=>{"$all"=>[1]}, "$and"=>[{"a"=>{"$all"=>[2]}}]}
#   options:  {}
#   class:    Band
#   embedded: false>

Default Mongoid 7.0 behavior:

Band.all(a: 1).all(a: 2)
# => #<Mongoid::Criteria
#   selector: {"a"=>{"$all"=>[1, 2]}}
#   options:  {}
#   class:    Band
#   embedded: false>

To achieve the same behavior in Mongoid 7.1, the desired merge strategy must be explicitly requested:

Band.all(a: 1).union.all(a: 2)
# => #<Mongoid::Criteria
#   selector: {"a"=>{"$all"=>[1, 2]}}
#   options:  {}
#   class:    Band
#   embedded: false>

Required Condition Arguments

Breaking change: nil arguments to Criteria methods are no longer accepted. For example, the following invocation is now an error:

Band.where(nil)

Breaking change: Most Criteria methods (other than logical operations) can no longer be called without arguments. For example, the following invocation is now an error:

Band.in

and, or, nor, not, any_of and where can be called without arguments.

Generated Queries

Minor change: Mongoid 7.1 will simplify the Criteria selectors where possible by eliding unnecessary logical operators, typically $and.

Example Mongoid 7.1 behavior:

Band.where(year: 2000).and(name: 'One')
# => #<Mongoid::Criteria
#   selector: {"year"=>2000, "name"=>"One"}
#   options:  {}
#   class:    Band
#   embedded: false>

Corresponding Mongoid 7.0 behavior:

Band.where(year: 2000).and(name: 'One')
# => #<Mongoid::Criteria
#   selector: {"year"=>2000, "$and"=>[{"name"=>"One"}]}
#   options:  {}
#   class:    Band
#   embedded: false>

Mongoid 7.1 also takes steps to produce the same selector shapes when semantically the same query is constructed using different code paths. For example, the following two approaches result in the same generated selector:

Band.where(name: /ne/).and(name: 'One')

Band.and({name: /ne/}, {name: 'One'})

# => #<Mongoid::Criteria
#   selector: {"name"=>/ne/, "$and"=>[{"name"=>"One"}]}
#   options:  {}
#   class:    Band
#   embedded: false>

Ruby Version Support

As of version 7.1, Mongoid supports Ruby 2.3+ and JRuby 9.2. Support for Ruby 2.2 and JRuby 9.1 has been dropped.

Changes in Mongoid 7.1.0

Improvement: Multiple atomic operations can now be grouped to be executed as a single atomic operation.

Improvement: Shard key declarations now support hashed shard keys, and a Rake task to shard collection has been added to the sharding management Rake tasks.

Changes in Mongoid 7.1.1

Breaking change: The behavior of any_of was reverted to its Mongoid 7.0 behavior. As was the case in Mongoid 7.0, any_of now does not treat the receiver as one of its operands:

Band.where(year: 1990).any_of({name: 'One'}, {name: 'Two'})
# => #<Mongoid::Criteria
#   selector: {"year"=>1990, "$or"=>[{"name"=>"One"}, {"name"=>"Two"}]}
#   options:  {}
#   class:    Band
#   embedded: false>

or behaves the same way in Mongoid 7.1.1 and 7.1.0:

Band.where(year: 1990).or({name: 'One'}, {name: 'Two'})
# => #<Mongoid::Criteria
#   selector: {"$or"=>[{"year"=>1990}, {"name"=>"One"}, {"name"=>"Two"}]}
#   options:  {}
#   class:    Band
#   embedded: false>

Minor change: The value of include_root_in_json is now properly respected throughout the model hierarchy. Previously the values set on model classes were ignored.

Improvement: Model.where can now be called with no arguments.

Improvement: Polymorphic belongs_to associations can now be eagerly loaded.

Changes in Mongoid 7.1.2

The model generator now creates a belongs_to association when a field type is specified to be belongs_to as the following example shows:

rails g model Comment message:text post:belongs_to

Previously, an embedded_in association was created in this case.

Upgrading to Mongoid 7.0

Significant improvements and changes in Mongoid 7.0 are listed below. Please note that improvements that have been backported to Mongoid 6.x are not included in this list.

The behavior of read-only attributes now matches that of ActiveRecord.

Referenced associations now support all dependent behaviors that ActiveRecord supports.

$unwind operator support added to the aggregation pipeline builder DSL.

background_indexing Mongoid configuration option added.

Mongoid 7.0 requires MongoDB server 2.6 or newer, Ruby 2.2.2 or higher and supports Rails 5.1-6.0.

New in version 7.0.3: Embedded matchers now support the $eq operator.

New in version 7.0.5: Mongoid now officially supports Rails 6.0.

Upgrading to Mongoid 6

Mongoid 6 is compatible with Rails 5 and requires Ruby 2.2.2 or higher.

Please see the list of behavior changes for version 6.0.0.rc0 and version 6.0.0.beta for specific changes that might be required in your code.

Upgrading to Mongoid 5

The underlying driver has changed from Moped to the official MongoDB Ruby driver. For all users dropping down to the driver level for operations, please see the driver documentation for help with that API.

All Mongoid configuration options have changed, as the underlying driver has changed from Moped to the official MongoDB Ruby driver. Please see the configuration section for a detailed description of all the new options.

All references to session are now replaced with client. This includes the mongoid.yml configuration, store_in options, and all exceptions and modules with Session in the name.

find_and_modify has been removed and replaced with 3 options: find_one_and_update, find_one_and_delete and find_one_and_replace.

text_search has been removed as it is now a $text option in a query from MongoDB 2.6 onward.

first and last no longer add an _id sort when no sorting options have been provided. In order to guarantee that a document is the first or last, it needs to now contain an explicit sort.

Mongoid 5 supports MongoDB 2.4 and higher only - MongoDB 2.2 is no longer supported.