.. _configuration:
*************
Configuration
*************
.. default-domain:: mongodb
.. contents:: On this page
:local:
:backlinks: none
:depth: 2
:class: singlecol
Mongoid is customarily configured through a ``mongoid.yml`` file that specifies
options and clients. The simplest configuration is as follows, which configures
Mongoid to talk to a MongoDB server at "localhost:27017" and use the database
named "mongoid".
.. code-block:: yaml
development:
clients:
default:
database: mongoid
hosts:
- localhost:27017
The top level key in the configuration file, ``development`` in the above
example, refers to the environment name which the application is executing in,
i.e. ``development``, ``test`` or ``production``. The third level key,
``default`` in the above example, refers to the Mongo client name.
Most applications will use a single client named ``default``.
Generating Default Configuration
================================
If you are using Ruby on Rails, you can have Mongoid generate a default
configuration file for you by running the following command:
.. code-block:: bash
rails g mongoid:config
The configuration file will be placed in ``config/mongoid.yml``.
If you are not using Ruby on Rails, you can copy the minimal configuration
given above and save it as ``config/mongoid.yml``.
Loading Mongoid Configuration
=============================
If you are using Ruby on Rails, Mongoid configuration is automatically loaded
for the current environment as stored in ``Rails.env`` when the application
loads.
You may need to configure the ORM for your application to be Mongoid by
adding the following to ``application.rb``:
.. code-block:: ruby
config.generators do |g|
g.orm :mongoid
end
If you are not using Ruby on Rails, Mongoid configuration must be loaded
manually. This can be done via the ``Mongoid.load!`` method, which takes
the configuration file path as its argument, as follows:
.. code-block:: ruby
# Use automatically detected environment name
Mongoid.load!("path/to/your/mongoid.yml")
# Specify environment name manually
Mongoid.load!("path/to/your/mongoid.yml", :production)
When Mongoid is asked to automatically detect the environment name,
it does so by examining the following sources, in order:
- If ``Rails`` top level constant is defined, ``Rails.env``.
- If ``Sinatra`` top level constant is defined, ``Sinatra::Base.environment``.
- The ``RACK_ENV`` environment variable.
- The ``MONGOID_ENV`` environment variable.
It is also possible to configure Mongoid directly in Ruby, without using
a configuration file. This configuration style does not support the concept
of environments - whatever configuration is provided, it is applied to the
current environment - but it does support defining multiple clients.
.. code-block:: ruby
Mongoid.configure do |config|
config.clients.default = {
hosts: ['localhost:27017'],
database: 'my_db',
}
config.log_level = :warn
end
.. note::
Mongoid must be configured *before* any component of it is used or referenced.
Once a component is used or referenced, changing configuration may not apply
changes to already instantiated components.
.. _configuration-options:
Mongoid Configuration Options
=============================
The following annotated example ``mongoid.yml`` demonstrates how Mongoid
can be configured.
Mongoid delegates to the Ruby driver for client configuration. Please review
`the driver documentation `_
for details on driver options.
.. code-block:: yaml
development:
# Configure available database clients. (required)
clients:
# Define the default client. (required)
default:
# A uri may be defined for a client:
# uri: 'mongodb://user:password@myhost1.mydomain.com:27017/my_db'
# Please see driver documentation for details. Alternatively, you can
# define the following:
#
# Define the name of the default database that Mongoid can connect to.
# (required).
database: my_db
# Provide the hosts the default client can connect to. Must be an array
# of host:port pairs. (required)
hosts:
- myhost1.mydomain.com:27017
- myhost2.mydomain.com:27017
- myhost3.mydomain.com:27017
options:
# These options are Ruby driver options, documented in
# https://mongodb.com/docs/ruby-driver/current/reference/create-client/
# Change the default write concern. (default = { w: 1 })
write:
w: 1
# Change the default read preference. Valid options for mode are: :secondary,
# :secondary_preferred, :primary, :primary_preferred, :nearest
# (default: primary)
read:
mode: :secondary_preferred
tag_sets:
- use: web
# The name of the user for authentication.
user: 'user'
# The password of the user for authentication.
password: 'password'
# The user's database roles.
roles:
- 'dbOwner'
# Change the default authentication mechanism. Please see the
# driver documentation linked above for details on how to configure
# authentication. Valid options are :aws, :gssapi, :mongodb_cr,
# :mongodb_x509, :plain, :scram and :scram256 (default on 3.0
# and higher servers is :scram, default on 2.6 servers is :plain)
auth_mech: :scram
# Specify the auth source, i.e. the database or other source which
# contains the user's login credentials. Allowed values for auth source
# depend on the authentication mechanism, as explained in the server documentation:
# https://mongodb.com/docs/manual/reference/connection-string/#mongodb-urioption-urioption.authSource
# If no auth source is specified, the default auth source as
# determined by the driver will be used. Please refer to:
# https://mongodb.com/docs/ruby-driver/current/reference/authentication/#auth-source
auth_source: admin
# Connect directly to and perform all operations on the specified
# server, bypassing replica set node discovery and monitoring.
# Exactly one host address must be specified. (default: false)
#direct_connection: true
# Deprecated. Force the driver to connect in a specific way instead
# of automatically discovering the deployment type and connecting
# accordingly. To connect directly to a replica set node bypassing
# node discovery and monitoring, use direct_connection: true instead
# of this option. Possible values: :direct, :replica_set, :sharded.
# (default: none)
#connect: :direct
# Change the default time in seconds the server monitors refresh their status
# via hello commands. (default: 10)
heartbeat_frequency: 10
# The time in seconds for selecting servers for a near read preference. (default: 0.015)
local_threshold: 0.015
# The timeout in seconds for selecting a server for an operation. (default: 30)
server_selection_timeout: 30
# The maximum number of connections in the connection pool. (default: 5)
max_pool_size: 5
# The minimum number of connections in the connection pool. (default: 1)
min_pool_size: 1
# The time to wait, in seconds, in the connection pool for a connection
# to be checked in before timing out. (default: 1)
wait_queue_timeout: 1
# The time to wait to establish a connection before timing out, in seconds.
# (default: 10)
connect_timeout: 10
# How long to wait for a response for each operation sent to the
# server. This timeout should be set to a value larger than the
# processing time for the longest operation that will be executed
# by the application. Note that this is a client-side timeout;
# the server may continue executing an operation after the client
# aborts it with the SocketTimeout exception.
# (default: nil, meaning no timeout)
socket_timeout: 5
# The name of the replica set to connect to. Servers provided as seeds that do
# not belong to this replica set will be ignored.
replica_set: my_replica_set
# Whether to connect to the servers via ssl. (default: false)
ssl: true
# The certificate file used to identify the connection against MongoDB.
ssl_cert: /path/to/my.cert
# The private keyfile used to identify the connection against MongoDB.
# Note that even if the key is stored in the same file as the certificate,
# both need to be explicitly specified.
ssl_key: /path/to/my.key
# A passphrase for the private key.
ssl_key_pass_phrase: password
# Whether or not to do peer certification validation. (default: true)
ssl_verify: true
# The file containing a set of concatenated certification authority certifications
# used to validate certs passed from the other end of the connection.
ssl_ca_cert: /path/to/ca.cert
# Compressors to use. (default is to not use compression)
compressors: [zlib]
# Configure Mongoid-specific options. (optional)
options:
# Application name that is printed to the MongoDB logs upon establishing
# a connection in server versions 3.4 or greater. Note that the name
# cannot exceed 128 bytes in length. It is also used as the database name
# if the database name is not explicitly defined. (default: nil)
app_name: MyApplicationName
# Mark belongs_to associations as required by default, so that saving a
# model with a missing belongs_to association will trigger a validation
# error. (default: true)
belongs_to_required_by_default: true
# Maintain broken behavior of sum over empty result sets for backwards
# compatibility. When calculating a sum on a field with a null context,
# for example:
#
# Product.none.sum(:price)
#
# ... return field name (`:price') instead of 0.
#
# When calculating a sum via a database query with an empty result set,
# for example:
#
# Product.where(impossible_condition: true).sum(:price)
#
# ... return nil instead of 0.
# (default: false)
#broken_aggregables: true
# Ignore aliased fields in embedded documents when performing pluck and
# distinct operations, for backwards compatibility.
# (default: false)
#broken_alias_handling: true
# Maintain broken `and' method behavior that existed in Mongoid 7.3
# and earlier for backwards compatibility: in some situations, conditions
# already present in a Criteria object would be replaced by newer
# conditions when `and' method is used instead of the new conditions
# being added to the existing conditions. This would happen when using
# the same operator on the same field multiple times. For example:
#
# Band.where(id: 1).and({year: {'$in' => [2020]}}, {year: {'$in' => [2021]}}).where(id: 2)
#
# yields the following criteria:
#
# 1, "year"=>{"$in"=>[2020]}, "$and"=>[{"_id"=>2}]}
# options: {}
# class: Band
# embedded: false>
#
# This is obviously incorrect as the {"$in"=>[2021]} clause is lost.
# Notice that the clause is only lost when both clauses are added using
# the #and method.
# (default: false)
#broken_and: true
# When exiting a nested `with_scope' block, set the current scope to
# nil instead of the parent scope for backwards compatibility.
# (default: false)
#broken_scoping: true
# Maintain broken update behavior in some cases for backwards
# compatibility.
#
# In Mongoid 7.3 and earlier, when assigning a value to an embedded
# document, then setting it to nil, then assigning the original value
# to it again, the second update would not work and the value for the
# embedded document would remain nil. Take this case:
#
# canvas.palette = palette
# canvas.palette = nil
# canvas.palette = palette
#
# ... where canvas embeds_one palette.
#
# In Mongoid 7.3 and earlier, canvas.palette would be nil when we would
# expect it to be palette. Set this option to true to keep this behavior,
# set the option to false to perform the second update correctly.
# (default: false)
#broken_updates: true
# Time objects in Ruby have nanosecond precision, whereas MongoDB server
# can only store times with millisecond precision. Set this option to
# true to truncate times to millisecond precision when performing
# queries on already loaded embedded associations (this is also called
# "embedded matching" and is done completely in Ruby), to obtain the
# same query results when performing time comparisons regardless of
# which documents are being queried. Setting this option to false will
# produce different results for queries on embedded associations that
# are already loaded into memory vs queries on unloaded associations and
# top-level models. (default: true)
#compare_time_by_ms: false
# Set the global discriminator key. (default: "_type")
discriminator_key: "_type"
# Raise an exception when a field is redefined. (default: false)
duplicate_fields_exception: false
# Include the root model name in json serialization. (default: false)
include_root_in_json: false
# Include the _type field in serialization. (default: false)
include_type_for_serialization: false
# Whether to join nested persistence contexts for atomic operations
# to parent contexts by default. (default: false)
join_contexts: false
# When this flag is true, the attributes method on a document will return
# a BSON::Document when that document is retrieved from the database, and
# a Hash otherwise. When this flag is false, the attributes method will
# always return a Hash. (default: false)
#legacy_attributes: true
# Maintain legacy behavior of pluck and distinct, which does not demongoize
# values on returning them. Setting this option to false will cause
# pluck and distinct to return demongoized values. Setting this option to
# false will also allow retrieving *_translations fields from pluck and
# distinct and will return embedded values themselves (i.e. without
# putting them in a hash).
# (default: false)
#legacy_pluck_distinct: true
# Maintain legacy behavior of === on Mongoid document classes, which
# returns true in a number of cases where Ruby's === implementation would
# return false. Note that the behavior of === on Mongoid document
# instances differs from both the behavior of === on document classes
# and from Ruby's behavior of === on simple object instances regardless
# of the value of this option.
# (default: false)
#legacy_triple_equals: true
# Set the Mongoid and Ruby driver log levels when Mongoid is not using
# Ruby on Rails logger instance. (default: :info)
log_level: :info
# When using the BigDecimal field type, store the value in the database
# as a BSON::Decimal128 instead of a string. (default: true)
#map_big_decimal_to_decimal128: true
# Force ``BSON::ObjectId#as_json`` method to return the hash
# { "$oid" => id.to_s }. When this option is false, and bson-ruby 5
# is used, the return value will be the hexadecimal ObjectId string only.
# (default: false)
#object_id_as_json_oid: true
# When chaining the same operators that use the same field, setting this
# feature flag to false will cause those operators to be combined using an
# and. Setting this feature flag to true will cause the later chained
# operators to overwrite the earlier ones. (default: false)
#overwrite_chained_operators: false
# Preload all models in development, needed when models use
# inheritance. (default: false)
preload_models: false
# Raise an error when performing a #find and the document is not found.
# (default: true)
raise_not_found_error: true
# Raise an error when defining a scope with the same name as an
# existing method. (default: false)
scope_overwrite_exception: false
# Use ActiveSupport's time zone in time operations instead of
# the Ruby default time zone. See the time zone section below for
# further information. (default: true)
use_activesupport_time_zone: true
# Return stored times as UTC. See the time zone section below for
# further information. Most applications should not use this option.
# (default: false)
use_utc: false
# (Deprecated) In MongoDB 4.0 and earlier, set whether to create
# indexes in the background by default. (default: false)
background_indexing: false
# Configure driver-specific options. (optional)
driver_options:
# When this flag is turned off, inline options will be correctly
# propagated to Mongoid and Driver finder methods. When this flag is turned
# on those options will be ignored. For example, with this flag turned
# off, Band.all.limit(1).count will take the limit into account, while
# when this flag is turned on, that limit is ignored. The affected driver
# methods are: aggregate, count, count_documents, distinct, and
# estimated_document_count. The corresponding Mongoid methods are also
# affected. (default: false, driver version: 2.18.0+)
#broken_view_options: false
# Validates that there are no atomic operators (those that start with $)
# in the root of a replacement document, and that there are only atomic
# operators at the root of an update document. If this feature flag is on,
# an error will be raised on an invalid update or replacement document,
# if not, a warning will be output to the logs. This flag does not affect
# Mongoid as of 8.0, but will affect calls to driver update/replace
# methods. (default: false, driver version: 2.18.0+)
#validate_update_replace: false
.. _load-defaults:
Version Based Defaults
======================
Mongoid supports setting the configuration options to the defaults for specific
versions. This is useful for upgrading to a new Mongoid version. When upgrading
your Mongoid version, the following should be set on ``Mongoid::Config``:
.. code:: ruby
Mongoid.configure do |config|
config.load_defaults
end
This way, when upgrading to a new version of Mongoid, your code will run with
the configuration options from the previous version of Mongoid. Then,
one-by-one, you can change the feature flags for the new version, and test that
your code still acts as expected. Once all of the new feature flags have been
accounted for, the call to ``load_defaults`` can be changed to take in the *new*
version, and all of the changed feature flags can be removed. For example, say
we're upgrading from 7.5 to 8.0. Between these two versions, only two feature
flags were added: ``legacy_attributes`` and ``map_big_decimal_to_decimal128``.
Before upgrading to Mongoid 8, the following line can be added:
.. code:: ruby
Mongoid.configure do |config|
config.load_defaults 7.5
end
Now, after upgrading, those two feature flags will default to their 7.5
functionality (``legacy_attributes: true, map_big_decimal_to_decimal128: false``).
Now you can set these feature flags one-by-one and flip them to their 8.0
behavior:
.. code:: ruby
Mongoid.configure do |config|
config.load_defaults 7.5
config.legacy_attributes = false
# config.map_big_decimal_to_decimal128 = true
end
It is advised to do these one at a time, so I have left the second flag
commented out. After verifying your code works as expected with the
``legacy_attributes`` flag turned off, the ``map_big_decimal_to_decimal128``
setting can be uncommented. Once that functionality is verified as well, both
of those lines can be removed and the ``load_defaults`` replaced with:
.. code:: ruby
Mongoid.configure do |config|
config.load_defaults 8.0
end
ERb Preprocessing
=================
When loading a configuration file, Mongoid processes it with ERb before
parsing it as YAML. This allows, for example, constructing the contents of
the configuration file at runtime based on environment variables:
.. code-block:: yaml
development:
clients:
default:
uri: "<%= ENV['MONGODB_URI'] %>"
.. note::
When outputting values from ERb, ensure the values are valid YAML and
escape them as needed.
.. note::
Since ERb rendering is performed prior to YAML parsing, all ERb directives
in the configuration file are evaluated, including those occurring in YAML
comments.
Logging
=======
When configuring logging, it is important to keep in mind that Mongoid
provides a model layer on top of the MongoDB Ruby driver, and the driver
dispatches the CRUD operations to the MongoDB deployment. Therefore, some
of the logging output in an application using Mongoid comes from Mongoid
itself, and some comes from the driver.
The Mongo client is a Ruby driver client instance, therefore
the logger of a Mongo client is the Ruby driver logger, not the Mongoid
logger. In other words:
.. code-block:: ruby
# Ruby driver logger, not Mongoid logger
Mongoid.client(:default).logger
Depending on whether Mongoid is used in a Ruby on Rails application, and how
both Mongoid and Ruby driver are configured, they may use the same logger
instance or different instances, potentially with different configurations.
In Ruby on Rails Application
----------------------------
When used in a Ruby on Rails application, Mongoid by default inherits
the logger and the log level from Rails, and sets the driver's logger
to the same logger instance:
.. code-block:: ruby
Rails.logger === Mongoid.logger
# => true
Mongoid.logger === Mongo::Logger.logger
# => true
To change the log level, use `standard Rails configuration
`_.
Place the following in one of environment configuration files, such as
``config/environments/production.rb``:
.. code-block:: ruby
Rails.application.configure do
config.log_level = :debug
end
.. note::
The ``log_level`` Mongoid `configuration option `_
is not used when Mongoid operates in a Rails application, because Mongoid
inherits Rails' log level in this case.
To configure either Mongoid or driver logger differently from the Rails logger,
use an initializer as follows:
.. code-block:: ruby
Rails.application.configure do
config.after_initialize do
# Change Mongoid log destination and/or level
Mongoid.logger = Logger.new(STDERR).tap do |logger|
logger.level = Logger::DEBUG
end
# Change driver log destination and/or level
Mongo::Logger.logger = Logger.new(STDERR).tap do |logger|
logger.level = Logger::DEBUG
end
end
end
.. note::
There is currently no provision in the Ruby standard library ``Logger``
to return the log device (i.e. the ``IO`` object) that a logger is using.
To have, for example, Mongoid and/or the Ruby driver log to the
standard Rails log file (e.g. ``log/development.log``) but with a
different level from standard Rails logger (``Rails.logger``), the
file must be opened separately and the resulting ``IO`` object passed to
the ``Logger`` constructor.
.. note::
Since by default Mongoid sets its own logger and the driver's logger to the
same instance as the Rails logger, modifying any of the instances affects
all of them. For example the following changes log level for all three
loggers, unless the application assigned a separate ``Logger`` instance
to `Mongo::Logger.logger`` as described above:
.. code-block:: ruby
Mongoid::Logger.logger.level = Logger::DEBUG
Standalone
----------
When not loaded in a Ruby on Rails application, Mongoid respects the
``log_level`` top level `configuration option `_.
It can be given in the configuration file as follows:
.. code-block:: yaml
development:
clients:
default:
# ...
options:
log_level: :debug
... or when configuring Mongoid inline:
.. code-block:: ruby
Mongoid.configure do |config|
config.log_level = :debug
end
The default log destination in Mongoid 7.1 and higher is standard error.
The default log destination in Mongoid 7.0 and lower is standard output.
To change the log destination, create a new logger instance as follows:
.. code-block:: ruby
Mongoid.logger = Logger.new(STDERR).tap do |logger|
logger.level = Logger::DEBUG
end
To change the Ruby driver log level or destination:
.. code-block:: ruby
Mongo::Logger.logger = Logger.new(STDERR).tap do |logger|
logger.level = Logger::DEBUG
end
To set the driver logger to be the same as the Mongoid logger:
.. code-block:: ruby
Mongo::Logger.logger = Mongoid.logger
.. note::
Mongoid does not alter the driver's logger when running in
standalone mode.
.. _time-zones:
Time Zones
==========
Ruby has limited time zone support in the standard library. ActiveSupport
(which Mongoid depends on) offers more comprehensive time zone support.
Importantly, Ruby and ActiveSupport may be configured with different default
time zones.
While a thorough treatment of time zones in Ruby is outside the scope
of this tutorial, the easiest and most reliable way of achieving correct
time zone handling is as follows:
1. Set the operating system's time zone to UTC. For example, on Linux:
.. code-block:: bash
cp /usr/share/zoneinfo/UTC /etc/localtime
2. Set ActiveSupport's time zone to UTC:
.. code-block:: ruby
# If using Rails, in application.rb:
class Application < Rails::Application
config.time_zone = 'UTC'
end
# If not using Rails:
Time.zone = 'UTC'
3. Store and persist all times in UTC. Perform all calculations on times
in UTC.
4. When working with user input in local time, convert such user input to UTC
times as soon as possible, and then work with the UTC times.
5. When rendering or otherwise presenting times, convert them to local time
after performing all calculations, when actually rendering.
6. Date to time (for example, the time when a particular day starts or ends)
conversions are a common source of errors. Such conversions should generally
be performed while explicitly specifying the time zone in which the date
is understood to be.
Applications using Mongoid should generally configure ActiveSupport's
time zone as described above, and then use ``Time.zone`` rather than ``Time``
(for example, ``Time.zone.now`` instead of ``Time.now``) to invoke the
ActiveSupport time zone machinery. This also helps achieve correct results
when the system time zone is not UTC, as is common in development environments.
Note that MongoDB stores all times in UTC without time zone information.
Mongoid offers the following time zone-related configuration options:
- ``use_activesupport_time_zone``: If true, prefer to work with times using
``ActiveSupport::TimeWithZone``. Values in fields of type ``Time``
will be returned as instances of ``ActiveSupport::TimeWithZone``.
When parsing times without time zone information (such as when
mongoizing strings or arrays to time), assume the times are specified
in ActiveSupport's time zone. This is the default.
If false, prefer to work with times using Ruby standard library ``Time`` class.
Values in fields of type ``Time`` will be returned as ``Time`` instances.
When parsing times without time zone information, assume the times
are specified in the Ruby time zone.
Note that the ``use_activesupport_time_zone`` setting does not affect
fields of types ``Date`` or ``DateTime``, which use ``Date`` and
``DateTime`` classes for their values, respectively.
Also note that Mongoid may still utilize both ``Time`` and
``ActiveSupport::TimeWithZone`` classes internally, as appropriate,
regardless of the ``use_activesupport_time_zone`` setting.
- ``use_utc``:
If true, times stored in MongoDB will be returned in UTC.
If false, times stored in MongoDB will be returned in local time
(as instances of either ``Time`` or ``ActiveSupport::TimeWithZone``,
respectively in the Ruby default time zone or the ActiveSupport time zone,
based on the value of ``use_activesupport_time_zone`` setting).
The default is false.
The ``use_utc`` setting does not affect how times are parsed - parsing
is always done in local time when the input being parsed does not
include time zone information. To parse dates in UTC, set the
system/Ruby or ActiveSupport time zone to UTC (as mentioned above,
setting all three to UTC leads to the fewest headaches).
Setting ``use_activesupport_time_zone`` to true and ``Time.zone`` to
UTC (and using ActiveSupport time machinery for all time-related
operations) is recommended over setting ``use_utc`` to true.
Note that ``use_activesupport_time_zone`` and ``use_utc`` options do not
throw away time zone information when it is available. For example, a Time
instance does have an associated time zone, and this time zone will be used
even if it is different from ActiveSupport's configured time zone when
``use_activesupport_time_zone`` is true.
Configuring ``SSLContext``
==========================
It may be desirable to further configure TLS options in your application, for
example by enabling or disabling certain ciphers.
This can be done by setting TLS context hooks on the Ruby driver -- TLS context
hooks are user-provided ``Proc``s that will be invoked before any TLS socket
connection in the driver and can be used to modify the underlying
``OpenSSL::SSL::SSLContext`` object used by the socket.
To set TLS context hooks, add ``Proc``s to the ``Mongo.tls_context_hooks``
array. This can be done in an initializer. The example below adds a hook
that only enables the "AES256-SHA" cipher.
.. code-block:: ruby
Mongo.tls_context_hooks.push(
Proc.new { |context|
context.ciphers = ["AES256-SHA"]
}
)
# Only the AES256-SHA cipher will be enabled from this point forward
Every ``Proc`` in ``Mongo.tls_context_hooks`` will be passed an
``OpenSSL::SSL::SSLContext`` object as its sole argument. These procs will
be executed sequentially during socket creation.
..warning ::
TLS context hooks are global and will affect all ``Mongo::Client`` instances
in an application.
For more information about TLS context hooks, including best practices for
assigning and removing them, see `the Ruby driver documentation `_.
Client-Side Encryption
======================
When loading the configuration file, Mongoid permits the file to contain
``BSON::Binary`` instances which are used for specifying ``keyId`` in
the schema map for `client-side encryption
`_,
as the following example shows:
.. code-block:: yaml
development:
clients:
default:
database: blog_development
hosts: [localhost:27017]
options:
auto_encryption_options:
key_vault_namespace: 'keyvault.datakeys'
kms_providers:
local:
key: "z7iYiYKLuYymEWtk4kfny1ESBwwFdA58qMqff96A8ghiOcIK75lJGPUIocku8LOFjQuEgeIP4xlln3s7r93FV9J5sAE7zg8U"
schema_map:
blog_development.comments:
properties:
message:
encrypt:
keyId:
- !ruby/object:BSON::Binary
data: !binary |-
R/AgNcxASFiiJWKXqWGo5w==
type: :uuid
bsonType: "string"
algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
bsonType: "object"
Usage with Forking Servers
==========================
When using Mongoid with a forking web server such as Puma, Unicorn or
Passenger, it is recommended to not perform any operations on Mongoid models
in the parent process prior to the fork.
When a process forks, Ruby threads are not transferred to the child processes
and the Ruby driver Client objects lose their background monitoring. The
application will typically seem to work just fine until the deployment
state changes (for example due to network errors, a maintenance event) at
which point the application is likely to start getting ``NoServerAvailable``
exception when performing MongoDB operations.
If the parent process needs to perform operations on the MongoDB database,
reset all clients in the workers after they forked. How to do so depends
on the web server being used.
If the parent process does not need to perform operations on the MongoDB
database after child processes are forked, close the clients in the parent
prior to forking children. If the parent process performs operations on a Mongo
client and does not close it, the parent process will continue consuming a
connection slot in the cluster and will continue monitoring the cluster for
as long as the parent remains alive.
.. note::
The close/reconnect pattern described here should be used with Ruby driver
version 2.6.2 or higher. Previous driver versions did not recreate
monitoring threads when reconnecting.
Puma
----
Use the ``on_worker_boot`` hook to reconnect clients in the workers and
the ``before_fork`` hook to close clients in the parent process
(`Puma documentation `_):
.. code-block:: ruby
on_worker_boot do
Mongoid::Clients.clients.each do |name, client|
client.close
client.reconnect
end
end
before_fork do
Mongoid.disconnect_clients
end
Unicorn
-------
Use the ``after_fork`` hook to reconnect clients in the workers and
the ``before_fork`` hook to close clients in the parent process
(`Unicorn documentation `_):
.. code-block:: ruby
after_fork do |server, worker|
Mongoid::Clients.clients.each do |name, client|
client.close
client.reconnect
end
end
before_fork do |server, worker|
Mongoid.disconnect_clients
end
Passenger
---------
Use the ``starting_worker_process`` hook to reconnect clients in the workers
(`Passenger documentation
`_).
Passenger does not appear to have a hook that is invoked in the parent process
before the workers are forked.
.. code-block:: ruby
if defined?(PhusionPassenger)
PhusionPassenger.on_event(:starting_worker_process) do |forked|
Mongoid::Clients.clients.each do |name, client|
client.close
client.reconnect
end
end
end
.. _query-cache-middleware:
Query Cache Middleware
======================
.. note::
When used with Ruby driver version 2.15 or newer, Mongoid's Query Cache
Middleware delegates to :ref:`the driver's Query Cache Middleware
`.
Mongoid provides a Rack middleware which enables the :ref:`Query Cache
` for the duration of each web request. Below is an example of
how to enable the Query Cache Middleware in a Ruby on Rails application:
.. code-block:: ruby
# config/application.rb
# Add Mongoid::QueryCache::Middleware at the bottom of the middleware stack
# or before other middleware that queries MongoDB.
config.middleware.use Mongoid::QueryCache::Middleware
Please refer to the `Rails on Rack guide
`_
for more information about using Rack middleware in Rails applications.
Development Configuration
=========================
Driver's default configuration is suitable for production deployment.
In development, some settings can be adjusted to provide a better developer
experience.
- ``:server_selection_timeout``: set this to a low value (e.g., ``1``)
if your MongoDB server is running locally and you start it manually. A low
server selection timeout will cause the driver to fail quickly when there is
no server running.
Sample recommended development configuration:
.. code-block:: yaml
development:
clients:
default:
database: mongoid
hosts:
- localhost:27017
options:
server_selection_timeout: 1