Skip to content

Release candidate for 9.1.0#6145

Open
jamis wants to merge 1 commit intomongodb:masterfrom
jamis:rc-9.1.0
Open

Release candidate for 9.1.0#6145
jamis wants to merge 1 commit intomongodb:masterfrom
jamis:rc-9.1.0

Conversation

@jamis
Copy link
Copy Markdown
Contributor

@jamis jamis commented May 6, 2026

The MongoDB Ruby team is pleased to announce version 9.1.0 of the mongoid gem - an Ruby ODM for MongoDB. This is a new minor release in the 9.x series of Mongoid.

Install this release using RubyGems via the command line as follows:

gem install -v 9.1.0 mongoid

Or simply add it to your Gemfile:

gem 'mongoid', '9.1.0'

Have any feedback? Click on through to MongoDB's JIRA and open a new ticket to let us know what's on your mind 🧠.

New Features

MONGOID-5411 allow results to be returned as demongoized hashes (PR)

Mongoid now supports a new raw directive when building queries. When present, the resulting query will be returned as hashes, rather than instantiated document models. The hashes will not be "demongoized" -- the values will be returned exactly as provided by the database, directly.

If you specify typed: true, the hashes will be returned with the values translated from the raw value stored in the database, into the corresponding type defined by the field definitions on the model. (That is to say, they will be "demongoized".)

For example:

result = Person.raw.first
p result  #=> {"_id"=>BSON::ObjectId(...), "name" => "...", "birth_date" => 2002-01-01 00:00:00 -0600, ... }

result = Person.raw(typed: true).first
p result  #=> {"_id"=>BSON::ObjectId(...), "name" => "...", "birth_date" => 2002-01-01, ... }

results = Person.where(...).limit(...).raw
p results.to_a #=> [ { "_id"=>BSON::ObjectId(...), ... }, { "_id"=>BSON::ObjectId(...), ... }, ... ]

The typed: true option will also honor embedded documents, correctly demongoizing the embedded hashes according to their declared types.

MONGOID-5752 Add Mongoid::Criteria#to_mql (PR)

To help with inspecting the queries that Mongoid generates, you can now call #to_mql on Criteria instances.

Person.where(...).to_mql

MONGOID-5827 Allow duplicate indexes to be declared (PR)

Mongoid will ignore indexes that differ only in the options used to declare them. This includes index names! This behavior will change in the future, but to ease the transition, you can set Mongoid.allow_duplicate_index_declarations = true to allow these near-identical indexes to be declared and processed by the server.

MONGOID-5882 Isolation state (PR)

Some applications will use threads for concurrency. Others will use fibers. Prior to this PR, Mongoid worked fine with threads, but it's internal state could get into odd states when run under fibers.

This PR allows applications to indicate which isolation level they wish to use, and Mongoid's state will be isolated to that scope.

# the default -- inherit the isolation level from `ActiveSupport::IsolatedExecutionState` if possible
Mongoid.isolation_level = :rails

# The following two explicit settings are supported:
Mongoid.isolation_level = :thread # the classic behavior
Mongoid.isolation_level = :fiber  # NEW!

When using the :fiber isolation level, Mongoid's internal state will be inherited from any parent fiber. If you want to make sure a fiber begins with a clean slate, you can wipe the isolation state with Mongoid::Threaded.reset!.

MONGOID-5892 - Treat serialize option only with values of nil and [] differently (PR)

Previously, passing only: [] to serializable_hash was treated the same as passing only: nil, meaning all fields were included. The correct behavior is to treat an empty array as "include no fields," suppressing all output.

This fix is gated behind the Mongoid.serializable_hash_with_legacy_only feature flag. In 9.1 and later, the flag defaults to true (legacy behavior); set it to false to opt into the new behavior. The default will flip to false in Mongoid 10.0, and the flag will be removed in 11.0.

MONGOID-5910 Implement enumerable methods on top level models (any?, many?, and one?) (PR)

You may now invoke the enumerable methods #any?, #many?, and #one? on Criteria instances. Invoking them at the class level will delegate to those methods, as well.

User.any? #-> returns true if any (1 or more) user records exist
User.where(admin: true).one? #-> returns true if there is exactly one admin record
User.where(banned: true).many? #-> returns true if there are "many" (2 or more) banned users

MONGOID-5731 Add Criteria#eager_load method to use aggregation pipeline for eager loading (PR)

A new Criteria method, #eager_load, has been added. It is effectively the same as using #includes (joining associations into a single result), but it uses an aggregation pipeline under the covers to issue a single query, instead of the multiple queries that #includes may emit. The #eager_load method will typically perform better on has_many and has_and_belongs_to_many associations, and on queries where you are joining on multiple belongs_to or has_one associations.

people = Person.eager_load(children: %i[ hobbies favorites ], :employer, :partner)

If you use #eager_load to attempt to join on an embedded association (embeds_one, embeds_many), it will silently fall back to using #includes.

MONGOID-5930 Add Mongoid::Config.allow_reparenting_via_nested_attributes (PR)

Add Mongoid::Config.allow_reparenting_via_nested_attributes, defaulting to false. When false, this prevents dependent has_many records from being reparented via use of nested attributes. When true, records may be reparented via nested attributes.

This setting will be removed in Mongoid 10, and reparenting via nested attributes will not be allowed.

MONGOID-5898 Add vector search support (PR)

Mongoid can now define vector search indexes, and provides a helper interface for querying documents by their semantic meaning using those indexed vector fields.

The simplest interface will define an Array field, and a corresponding vector search index:

class Article
  include Mongoid::Document
  
  # Define `embedding` as an Array field, and define a vector search index on it
  # with `dimensions` set to 1536.
  vector_field :embedding, dimensions: 1536
end

For more sophisticated configurations, you may also declare the field and the index separately:

class Article
  include Mongoid::Document

  field :embedding, type: Array
  vector_search_index :embedding_index,
    fields: [
      { type: 'vector',
        path: 'embedding',
        dimensions: 1536,
        ...
      }
    ]
end

Then, create the new search indexes:

$ rake db:mongoid:create_search_indexes

Once the indexes are created, you can query them using the vector_search method:

articles = Article.vector_search(vector, limit: 5)

# or, search for documents that are similar to an existing document
neighbors = article.vector_search(limit: 5)

MONGOID-5923 Support auto emdedding vector search indexes and searches (PR)

Mongoid can now define vector search indexes with auto-embedding, and provides a helper interface for querying documents by their semantic meaning using those indexed vector fields.

The simplest interface will define a String field using the voyage-4 model.

class Article
  include Mongoid::Document
  
  # Define `body` as a String field, indexed using the `voyage-4` auto-embedding model.
  auto_embed_field :body
end

You may declare the model and other parameters as well, if desired:

class Article
  include Mongoid::Document

  auto_embed_field :body,
                       model: 'voyage-4-large'
                       num_dimensions: 512,
                       quantization: 'binary',
                       similarity: 'cosine',
                       index: :body_index
end

Then, create the new search indexes:

$ rake db:mongoid:create_search_indexes

Once the indexes are created, you can query them using the auto_embed_search method:

articles = Article.auto_embed_search('machine learning', limit: 5)

# or, search for documents that are similar to an existing document
neighbors = article.auto_embed_search(limit: 5)

MONGOID-5750 Allow build_foo on embeds_one/has_one/etc. to specify the associated document's type (PR)

When using build_<association> on an embeds_one/has_one/belongs_to (etc.) association, you can now specify the type of the associated document. For example:

class Job
  include Mongoid::Document
  
  has_one :runner
end

class Runner
  include Mongoid::Document
  
  belongs_to :job
  field :name, type: String
end

class HeadlessRunner < Runner
end

job = Job.create
job.build_runner({ name: 'My Runner' }, HeadlessRunner)

The same syntax works with create_<association>.

MONGOID-5030 Short-circuit trivial queries where $in is given an empty array (PR)

When Mongoid.allow_short_circuit_queries == true, any top-level $in query condition that evaluates to an empty array will cause the query to be short-circuited, returning an empty array without sending the query to the database.

Mongoid.allow_short_circuit_queries = true
Document.in([]) #=> empty array, no database query issued

Mongoid.allow_short_circuit_queries = false
Document.in([]) #=> empty array, one database query issued

The Mongoid.allow_short_circuit_queries setting defaults to false.

Other New Features

  • MONGOID-4680 implement cache_version for better Rails caching support (PR)
  • Use in-memory aggregation for eager-loaded has_many associations (PR)
  • MONGOID-5720 deprecate Criteria#max_scan (PR)

Bug Fixes

MONGOID-5867 Merge touch updates into embedded document insert (PR)

When inserting an embedded document with a touchable parent (the default for embedded_in), Mongoid issues two separate update_one calls:

  1. $push — inserts the embedded document (insert_as_embedded)
  2. $set — updates updated_at on the parent chain (after_save touch callback)

This commit merges both into a single update_one, eliminating the redundant round-trip.

  • insert_as_embedded gathers touch updates via _gather_touch_updates and merges the $set into the same operation as the $push
  • The after_save touch callback checks a Threaded flag and skips the now-redundant persistence, while still running :touch callbacks and cleaning up dirty tracking
  • The Threaded flag follows the existing begin_autosave/exit_autosave/autosaved? pattern

MONGOID-5751 avoid unnecessary autosaves of unchanged subtrees (PR)

The legacy behavior of associations with autosave: true resulted in all #save being invoked on all children of those associations, whether those children actually needed it or not. All corresponding after_save hooks were invoked as well, recursively, clear to the bottom of the autosave tree.

This PR changes this behavior, ensuring that subtrees are only autosaved if there are any changed documents in the subtree. As there may be users that depend on the legacy behavior (expecting after_save hooks to be invoked even if the record has not changed, for instance), a feature flag has been added to allow the legacy behavior to be opted into.

Mongoid.autosave_saves_unchanged_documents = true

When true, the legacy behavior prevails. If your program depends on this legacy behavior, you are encouraged to rewrite the affected code, because this flag will go away in Mongoid 10, and the legacy autosave behavior will be removed.

Other Bug Fixes

  • MONGOID-5822: Embedded association validations break when association depends on parent update (PR)
  • Fix typos (PR)
  • MONGOID-5800 When initializing an embedded association with an invalid hash, got undefined method `with_indifferent_access' error (PR)
  • MONGOID-5842 fix numericality validator when given non-numeric strings (PR)
  • MONGOID-5927 init_atomic_updates from updatable.rb does not account for conflicts between set and unset commands (PR)
  • MONGOID-5922 fall back to #includes if #eager_load is given associations in different clusters (PR)
  • MONGOID-5759 ensure unpersisted documents are picked up via HasMany#find (PR)
  • MONGOID-5684 Ensure field_was returns the same type as field for hash-typed fields (PR)

Copilot AI review requested due to automatic review settings May 6, 2026 20:26
@jamis jamis requested a review from a team as a code owner May 6, 2026 20:26
@jamis jamis added the release-candidate The PR represents a potential candidate for a new release label May 6, 2026
@jamis jamis requested a review from comandeo-mongo May 6, 2026 20:26
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Bumps Mongoid’s declared version to 9.1.0 for the 9.1.0 release candidate, aligning the repository’s version metadata and the runtime Mongoid::VERSION constant.

Changes:

  • Update product.yml version number to 9.1.0.
  • Update Mongoid::VERSION to 9.1.0.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
product.yml Updates release metadata version number to 9.1.0.
lib/mongoid/version.rb Updates the gem’s runtime version constant to 9.1.0.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release-candidate The PR represents a potential candidate for a new release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants