***************** Creating a Client ***************** .. default-domain:: mongodb .. contents:: On this page :local: :backlinks: none :depth: 2 :class: singlecol Using ``Mongo::Client`` ======================= To connect to a MongoDB deployment, create a ``Mongo::Client`` object. Provide a list of hosts and options or a :manual:`connection string URI ` to the``Mongo::Client`` constructor. The client's selected database defaults to ``admin``. By default, the driver will automatically detect the topology used by the deployment and connect appropriately. To connect to a local standalone MongoDB deployment, specify the host and port of the server. In most cases you would also specify the database name to connect to; if no database name is specified, the client will use the ``admin`` database: .. code-block:: ruby Mongo::Client.new([ '127.0.0.1:27017' ], database: 'mydb') # Or using the URI syntax: Mongo::Client.new("mongodb://127.0.0.1:27017/mydb") .. note:: The hostname ``localhost`` is treated specially by the driver and will be resolved to IPv4 addresses only. To `connect to MongoDB Atlas `_, specify the Atlas deployment URI: .. code-block:: ruby Mongo::Client.new("mongodb+srv://username:myRealPassword@cluster0.mongodb.net/mydb?w=majority") The driver will discover all nodes in the cluster and connect to them as needed. Block Syntax ------------ Another way to create a Mongo::Client object is to use the block syntax: .. code-block:: ruby Mongo::Client.new(...) do |client| # work with the client end Note that when creating a client using this syntax, the client is automatically closed after the block finishes executing. Database Selection ================== By default, the client will connect to the ``admin`` database. The ``admin`` database is a special database in MongoDB often used for administrative tasks and storing administrative data such as users and roles (although users and roles may also be defined in other databases). In a sharded cluster, the ``admin`` database :manual:`exists on the config servers ` rather than the shard servers. Although it is possible to use the ``admin`` database for ordinary operations (such as storing application data), this is not recommended and the application should explicitly specify the database it wishes to use. The database can be specified during ``Client`` construction: .. code-block:: ruby # Using Ruby client options: client = Mongo::Client.new(['localhost'], database: 'mydb') # Using a MongoDB URI: client = Mongo::Client.new('mongodb://localhost/mydb') Given a ``Client`` instance, the ``use`` method can be invoked to obtain a new ``Client`` instance configured with the specified database: .. code-block:: ruby client = Mongo::Client.new(['localhost'], database: 'mydb') admin_client = client.use('admin') # Issue an administrative command admin_client.database.command(replSetGetConfig: 1).documents.first There are other special databases in MongoDB which should be only used for their stated purposes: - The :manual:`config ` database. - The :manual:`local ` database. - The ``$external`` database, which is used with :ref:`PLAIN `, :ref:`Kerberos ` and :ref:`X.509 ` authentication mechanisms. Connection Types ================ The driver will, by default, discover the type of deployment it is instructed to connect to (except for load-balanced deployments) and behave in the manner that matches the deployment type. The subsections below describe how the driver behaves in each of the deployment types as well as how to force particular behavior, bypassing automatic deployment type detection. Note that the detection of deployment type happens when the driver receives the first reply from any of the servers it is instructed to connect to (unless the load-balancing mode is requested, see below). The driver will remain in the discovered or configured topology even if the underlying deployment is replaced by one of a different type. In particular, when replacing a replica set with a sharded cluster at the same address the client instance must be recreated (such as by restarting the application) for it to communicate with the sharded cluster. Automatic discovery of load-balanced deployments is currently not supported. Load-balanced deployments will be treated as deployments of their underlying type, which would generally be sharded clusters. The driver will fail to correctly operate when treating a load-balanced deployment as a sharded cluster, therefore when the deployment is a load-balanced one the client must be explicitly configured to :ref:`connect to a load balancer `. Standalone Server Connection ---------------------------- If the deployment is a single server, also known as a standalone deployment, all operations will be directed to the specified server. If the server is shut down and replaced by a replica set node, the driver will continue sending all operations to that node, even if the node is or becomes a secondary. To force a standalone connection, see the :ref:`direct connection ` section below. .. _connect-replica-set: Replica Set Connection ---------------------- When connecting to a :manual:`replica set`, it is sufficient to pass the address of any node in the replica set to the driver. The node does not have to be the primary and it may be a hidden node. The driver will then automatically discover the remaining nodes. However, it is recommended to specify all nodes that are part of the replica set, so that in the event of one or more nodes being unavailable (for example, due to maintenance or reconfiguration) the driver can still connect to the replica set. Replica set connection examples: .. code-block:: ruby Mongo::Client.new([ '127.0.0.1:27017' ], database: 'mydb') Mongo::Client.new([ '127.0.0.1:27017', '127.0.0.1:27018' ], database: 'mydb') # Or using the URI syntax: Mongo::Client.new("mongodb://127.0.0.1:27017,127.0.0.1:27018/mydb") To make the driver verify the replica set name upon connection, pass it using the ``replica_set`` Ruby option or the ``replicaSet`` URI option: .. code-block:: ruby Mongo::Client.new([ '127.0.0.1:27017', '127.0.0.1:27018' ], database: 'mydb', replica_set: 'myapp') # Or using the URI syntax: Mongo::Client.new("mongodb://127.0.0.1:27017,127.0.0.1:27018/mydb?replicaSet=myapp") If the deployment is not a replica set or uses a different replica set name, all operations will fail (until the expected replica set is returned by the servers). It is also possible to force a replica set connection without specifying the replica set name. Doing so is generally unnecessary and is deprecated: .. code-block:: ruby Mongo::Client.new([ '127.0.0.1:27017', '127.0.0.1:27018' ], database: 'mydb', connect: :replica_set) # Or using the URI syntax: Mongo::Client.new("mongodb://127.0.0.1:27017,127.0.0.1:27018/mydb?connect=replica_set") To connect to a MongoDB Atlas cluster which is deployed as a replica set, connect to the URI: .. code-block:: ruby Mongo::Client.new("mongodb+srv://username:myRealPassword@cluster0.mongodb.net/test?w=majority") Please review the :ref:`SRV URI notes ` if using SRV URIs. .. _connect-sharded-cluster: Sharded Cluster Connection -------------------------- To connect to a :manual:`sharded cluster` deployment, specify the addresses of the ``mongos`` routers: .. code-block:: ruby Mongo::Client.new([ '1.2.3.4:27017', '1.2.3.5:27017' ], database: 'mydb') Mongo::Client.new("mongodb://1.2.3.4:27017,1.2.3.5:27017/mydb") Note that unlike a replica set connection, you may choose to connect to a subset of the ``mongos`` routers that exist in the deployment. The driver will monitor each router and will use the ones that are available (i.e., the driver will generally handle individual routers becoming unavailable due to failures or maintenance). When specifying the list of routers explicitly, the driver will not discover remaining routers that may be configured and will not attempt to connect to them. The driver will automatically balance the operation load among the routers it is aware of. To connect to a MongoDB Atlas cluster which is deployed as a sharded cluster, connect to the URI: .. code-block:: ruby Mongo::Client.new("mongodb+srv://username:myRealPassword@cluster0.mongodb.net/test?w=majority") When the driver connects to a sharded cluster via an SRV URI, it will periodically poll the SRV records of the address specified in the URI for changes and will automatically add and remove the ``mongos`` hosts to/from its list of servers as they are added and removed to/from the sharded cluster. To force a sharded cluster connection, use the ``connect: :sharded`` option. Doing so is generally unnecessary and is deprecated: .. code-block:: ruby Mongo::Client.new([ '127.0.0.1:27017', '127.0.0.1:27018' ], database: 'mydb', connect: :sharded) # Or using the URI syntax: Mongo::Client.new("mongodb://127.0.0.1:27017,127.0.0.1:27018/mydb?connect=sharded") Please review the :ref:`SRV URI notes ` if using SRV URIs. .. _direct-connection: Direct Connection ----------------- To disable the deployment type discovery and force all operations to be performed on a particular server, specify the ``direct_connection`` option: .. code-block:: ruby Mongo::Client.new([ '1.2.3.4:27017' ], database: 'mydb', direct_connection: true) # Or using the URI syntax: Mongo::Client.new("mongodb://1.2.3.4:27017/mydb?directConnection=true") Alternatively, the deprecated ``connect: :direct`` option is equivalent: .. code-block:: ruby Mongo::Client.new([ '1.2.3.4:27017' ], database: 'mydb', connect: :direct) # Or using the URI syntax: Mongo::Client.new("mongodb://1.2.3.4:27017/mydb?connect=direct") The direct connection mode is most useful for performing operations on a particular replica set node, although it also permits the underlying server to change type (e.g. from a replica set node to a ``mongos`` router, or vice versa). .. _load-balancer-connection: Load Balancer Connection ------------------------ Unlike other deployment types, the driver does not currently automatically detect a load-balanced deployment. To connect to a load balancer, specify the ``load_balanced: true`` Ruby option or the ``loadBalanced=true`` URI option: .. code-block:: ruby Mongo::Client.new([ '1.2.3.4:27017' ], database: 'mydb', load_balanced: true) # Or using the URI syntax: Mongo::Client.new("mongodb://1.2.3.4:27017/mydb?loadBalanced=true") When using these options, if the specified server is not a load balancer, the client will fail all operations (until the server becomes a load balancer). To treat the server as a load balancer even if it doesn't identify as such, use the ``connect: :load_balanced`` Ruby option or the ``connect=load_balanced`` URI option: .. code-block:: ruby Mongo::Client.new([ '1.2.3.4:27017' ], database: 'mydb', load_balanced: true, connect: :load_balanced) # Or using the URI syntax: Mongo::Client.new("mongodb://1.2.3.4:27017/mydb?loadBalanced=true&connect=load_balanced") .. _srv-uri-notes: SRV URI Notes ============= When the driver connects to a :manual:`mongodb+srv protocol ` URI, keep in mind the following: 1. SRV URI lookup is performed synchronously when the client is constructed. If this lookup fails for any reason, client construction will fail with an exception. When a client is constructed with a list of hosts, the driver will attempt to contact and monitor those hosts for as long as the client object exists. If one of these hosts does not resolve initially but becomes resolvable later, the driver will be able to establish a connection to such a host when it becomes available. The initial SRV URI lookup must succeed on the first attempt; subsequent host lookups will be retried by the driver as needed. 2. The driver looks up URI options in the DNS TXT records corresponding to the SRV records. These options can be overridden by URI options specified in the URI and by Ruby options, in this order. 3. Because the URI options are retrieved in a separate DNS query from the SRV lookup, in environments with unreliable network connectivity the URI option query may fail when the SRV lookup succeeds. Such a failure would cause the driver to use the wrong auth source leading to authentication failures. This can be worked around by explicitly specifying the auth source: .. code-block:: ruby Mongo::Client.new("mongodb+srv://username:myRealPassword@cluster0.mongodb.net/test?w=majority&authSource=admin") 4. If the topology of the constructed ``Client`` object is unknown or a sharded cluster, the driver will begin monitoring the specified SRV DNS records for changes and will automatically update the list of servers in the cluster. The updates will stop if the topology becomes a single or a replica set. .. _client-options: Client Options ============== ``Mongo::Client``'s constructor accepts a number of options configuring the behavior of the driver. The options can be provided in the options hash as Ruby options, in the URI as URI options, or both. If both a Ruby option and the analogous URI option are provided, the Ruby option takes precedence. Ruby Options ------------ .. note:: The options passed directly should be symbols. .. note:: Unless otherwise specified, Ruby options that deal with times are given in seconds. .. list-table:: :header-rows: 1 :widths: 25 40 10 15 * - Option - Description - Type - Default * - ``:app_name`` - Application name that is printed to the mongod logs upon establishing a connection in server versions >= 3.4. - ``String`` - none * - ``:auth_mech`` - Specifies the authenticaion mechanism to use. Can be one of: ``:gssapi``, ``:mongodb_cr``, ``:mongodb_x509``, ``:plain``, ``:scram``, ``:scram256``. GSSAPI (Kerberos) authentication :ref:`requires additional dependencies `. - ``Symbol`` - If user credentials are not supplied, ``nil``. If user credentials are supplied, the default depends on server version. MongoDB 4.0 and later: ``:scram256`` if user credentials correspond to a user which supports SCRAM-SHA-256 authentication, otherwise ``:scram``. MongoDB 3.0-3.6: ``:scram``. MongoDB 2.6: ``:mongodb_cr`` * - ``:auth_mech_properties`` - Provides additional authentication mechanism properties. The keys in properties are interpreted case-insensitively. When the client is created, keys are lowercased. - ``Hash`` - When using the GSSAPI authentication mechanism, the default properties are ``{service_name: "mongodb"}``. Otherwise the default is nil. * - ``:auth_source`` - Specifies the authentication source. - ``String`` - For MongoDB 2.6 and later: **admin** if credentials are supplied, otherwise the current database * - ``:auto_encryption_options`` - A ``Hash`` of options for configuring automatic encryption. - ``:key_vault_client`` - A client connected to the MongoDB instance storing the encryption data keys (``Mongo::Client``, defaults to the top-level client instance). - ``:key_vault_namespace`` - The namespace of the key vault collection in the format ``"database.collection"`` (``String``, required). - ``:kms_providers`` - Key management service configuration information. One or both of the keys ``:local`` and ``:aws`` must be specified (``Hash``, required). See the "The ``kms_providers`` option`` section of the :ref:`Client-Side Encryption tutorial` for more information about this option. - ``:schema_map`` - The JSONSchema for one or more collections specifying which fields should be encrypted (``Hash``, optional, defaults to ``nil``). - ``:bypass_auto_encryption`` - Whether to skip automatic encryption when performing database operations (``Boolean``, defaults to ``false``). - ``:extra_options`` - Options related to spawning mongocryptd (``Hash``, optional, defaults to ``nil``). For more information about formatting these options, see the "Auto-Encryption Options" section of the :ref:`Client-Side Encryption tutorial`. - ``Hash`` - none * - ``:bg_error_backtrace`` - Experimental. Controls whether and how backtraces are logged when errors occur in background threads. If ``true``, the driver will log complete backtraces. If set to a positive integer, the driver will log up to that many backtrace lines. If set to ``false`` or ``nil``, no backtraces will be logged. Other values are an error. - ``true``, ``false``, ``nil``, ``Integer`` - none * - ``:compressors`` - A list of potential compressors to use, in order of preference. Please see below for details on how the driver implements compression. - ``Array`` - none * - ``:connect`` - **Deprecated.** Disables deployment topology discovery normally performed by the dirver and forces the cluster topology to a specific type. Valid values are ``:direct``, ``:load_balanced``, ``:replica_set`` or ``:sharded``. If ``:load_balanced`` is used, the client will behave as if it is connected to a load balancer regardless of whether the server(s) it connects to advertise themselves as load balancers. - ``Symbol`` - none * - ``:connect_timeout`` - The number of seconds to wait to establish a socket connection before raising an exception. This timeout is also used for SRV DNS record resolution. ``nil`` and ``0`` mean no timeout. Client creation will fail with an error if an invalid timeout value is passed (such as a negative value or a non-numeric value). - ``Float`` - 10 * - ``:database`` - The name of the database to connect to. - ``String`` - admin * - ``:direct_connection`` - Connect directly to the specified host, do not discover deployment topology. - ``Boolean`` - false * - ``:heartbeat_frequency`` - The number of seconds for the server monitors to refresh server states asynchronously. - ``Float`` - 10 * - ``:id_generator`` - A custom object to generate ids for documents. Must respond to #generate. - ``Object`` - none * - ``:load_balanced`` - Whether to expect to connect to a load balancer. - ``Boolean`` - false * - ``:local_threshold`` - Specifies the maximum latency in seconds between the nearest server and the servers that can be available for selection to operate on. - ``Float`` - 0.015 * - ``:logger`` - A custom logger. - ``Object`` - ``Logger`` * - ``:max_idle_time`` - The maximum time, in seconds, that a connection can be idle before it is closed by the connection pool. *Warning:* when connected to a load balancer, the driver uses existing connections for iterating cursors (which includes change streams) and executing transactions. Setting an idle time via this option may cause the driver to close connections that are needed for subsequent operations, causing those operations to fail. - ``Integer`` - none * - ``:max_pool_size`` - The maximum size of the connection pool for each server. Setting this option to zero removes the max size limit from the connection pool, permitting it to grow to any number of connections. - ``Integer`` - 20 * - ``:max_read_retries`` - The maximum number of read retries, when legacy read retries are used. Set to 0 to disable legacy read retries. - ``Integer`` - 1 * - ``:max_write_retries`` - The maximum number of write retries, when legacy write retries are used. Set to 0 to disable legacy write retries. - ``Integer`` - 1 * - ``:min_pool_size`` - The minimum number of connections in the connection pool for each server. The driver will establish connections in the background until the pool contains this many connections. - ``Integer`` - 0 * - ``:monitoring`` - The monitoring object. - ``Object`` - none * - ``:password`` - The password of the user to authenticate with. - ``String`` - none * - ``:platform`` - Platform information to include in the metadata printed to the mongod logs upon establishing a connection in server versions >= 3.4. - ``String`` - none * - ``:read`` - Specifies the read preference mode and tag sets for selecting servers as a ``Hash``. Allowed Keys in the hash are ``:mode``, ``:tag_sets`` and ``:max_staleness``. .. code-block:: ruby { read: { mode: :secondary, tag_sets: [ "data_center" => "berlin" ], max_staleness: 5, } } If tag sets are provided, they must be an array of hashes. A server satisfies the read preference if its tags match any one hash in the provided tag sets. Each tag set must be a hash, and will be converted internally to a ``BSON::Document`` instance prior to being used for server selection. Hash keys can be strings or symbols. The keys are case sensitive. Hash values must be strings, and are matched exactly against the values in the replica set configuration. - ``Hash`` - ``{ :mode => :primary }`` * - ``:read_concern`` - Specifies the read concern options. The only valid key is ``level``, for which the valid values are ``:local``, ``:majority``, and ``:snapshot``. - ``Hash`` - none * - ``:read_retry_interval`` - The interval, in seconds, in which reads on a mongos are retried. - ``Integer`` - 5 * - ``:replica_set`` - When connecting to a replica set, this is the name of the set to filter servers by. - ``String`` - none * - ``:retry_writes`` - If a single-statement write operation fails from a network error, the driver automatically retries it once when connected to server versions 3.6+. - ``Boolean`` - true * - ``:sdam_proc`` - Since the client begins monitoring the deployment in background as soon as it is constructed, constructing a client and then subscribing to `SDAM `_ events in a separate statement may result in the subscriber not receiving some of the SDAM events. The ``:sdam_proc`` option permits adding event subscribers on the client being constructed before any SDAM events are published. Pass a ``Proc`` which will be called with the ``Client`` as the argument after the client's event subscription mechanism has been initialized but before any of the servers are added to the client. Use this ``Proc`` to set up SDAM event subscribers on the client. Note: the client is not fully constructed when the ``Proc`` provided in ``:sdam_proc is invoked, in particular the cluster is nil at this time. ``:sdam_proc`` procedure should limit itself to calling ``Client#subscribe`` and ``Client#unsubscribe`` methods on on the passed client only. - ``Proc`` - none * - ``:server_api`` - The server API version requested. This is a hash with the following allowed items: - ``:version`` (String) - ``:strict`` (true or false) - ``:deprecation_errors`` (true or false) Note that the server API version can only be specified as a Ruby option, not as a URI option, and it cannot be overridden for database and collection objects. If server API version is changed on a client (such as via the ``with`` call), the entire API version hash is replaced with the new specification (the old and the new individual fields are NOT merged). - ``Hash`` - none * - ``:server_selection_timeout`` - The number of seconds to wait for an appropriate server to be selected for an operation to be executed before raising an exception. - ``Float`` - 30 * - ``:socket_timeout`` - The number of seconds to wait for an operation to execute on a socket before raising an exception. ``nil`` and ``0`` mean no timeout. Client creation will fail with an error if an invalid timeout value is passed (such as a negative value or a non-numeric value). - ``Float`` - none * - ``:srv_max_hosts`` - The maximum number of mongoses that the driver will communicate with for sharded topologies. If this option is set to 0, there will be no maximum number of mongoses. If the given URI resolves to more hosts than ``:srv_max_hosts``, the client will ramdomly choose an ``:srv_max_hosts`` sized subset of hosts. Note that the hosts that the driver ignores during client construction will never be used. If the hosts chosen by the driver become unavailable, the client will quit working completely, even though the deployment has other functional mongoses. - ``Integer`` - 0 * - ``:srv_service_name`` - The service name to use in the SRV DNS query. - ``String`` - mongodb * - ``:ssl`` - Tell the client to connect to the servers via TLS. - ``Boolean`` - false * - ``:ssl_ca_cert`` - The file path containing concatenated certificate authority certificates used to validate certs passed from the other end of the connection. One of ``:ssl_ca_cert``, ``:ssl_ca_cert_string`` or ``:ssl_ca_cert_object`` (in order of priority) is required for ``:ssl_verify``. - ``String`` - none * - ``:ssl_ca_cert_object`` - An array of OpenSSL::X509::Certificate representing the certificate authority certificates used to validate certs passed from the other end of the connection. One of ``:ssl_ca_cert``, ``:ssl_ca_cert_string`` or ``:ssl_ca_cert_object`` (in order of priority) is required for ``:ssl_verify``. - ``Array< OpenSSL::X509::Certificate >`` - none * - ``:ssl_ca_cert_string`` - A string containing concatenated certificate authority certificates used to validate certs passed from the other end of the connection. One of ``:ssl_ca_cert``, ``:ssl_ca_cert_string`` or ``:ssl_ca_cert_object`` (in order of priority) is required for ``:ssl_verify``. - ``String`` - none * - ``:ssl_cert`` - Path to the client certificate file used to identify the application to the MongoDB servers. The file may also contain the certificate's private key; if so, the private key is ignored by this option. The file may also contain intermediate certificates forming the certificate chain from the client certificate to the CA certificate; any intermediate certificates will be parsed by the driver and provided to the OpenSSL context in ``extra_chain_cert`` attribute. If intermediate certificates are provided, they must follow the client certificate which must be the first certificate in the file. This option, if present, takes precedence over ``:ssl_cert_string`` and ``:ssl_cert_object`` options. - ``String`` - none * - ``:ssl_cert_object`` - The OpenSSL::X509::Certificate used to identify the application to the MongoDB servers. Only one certificate may be passed through this option. - ``OpenSSL::X509::Certificate`` - none * - ``:ssl_cert_string`` - A string containing the PEM-encoded certificate used to identify the application to the MongoDB servers. The string may also contain the certificate's private key; if so, the private key is ignored by this option. The string may also contain intermediate certificates forming the certificate chain from the client certificate to the CA certificate; any intermediate certificates will be parsed by the driver and provided to the OpenSSL context in ``extra_chain_cert`` attribute. If intermediate certificates are provided, they must follow the client certificate which must be the first certificatet in the string. This option, if present, takes precedence over the ``:ssl_cert_object`` option. - ``String`` - none * - ``:ssl_key`` - 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. This option, if present, takes precedence over the values of :ssl_key_string and :ssl_key_object. - ``String`` - none * - ``:ssl_key_object`` - The private key used to identify the connection against MongoDB. - ``OpenSSL::PKey`` - none * - ``:ssl_key_pass_phrase`` - A passphrase for the private key. - ``String`` - none * - ``:ssl_key_string`` - A string containing the PEM-encoded private key used to identify the connection against MongoDB. This parameter, if present, takes precedence over the value of option :ssl_key_object. - ``String`` - none * - ``:ssl_verify`` - Whether to perform peer certificate, hostname and OCSP endpoint validation. Note that the decision of whether to validate certificates will be overridden if ``:ssl_verify_certificate`` is set, the decision of whether to validate hostnames will be overridden if ``:ssl_verify_hostname`` is set and the decision of whether to validate OCSP endpoint will be overridden if ``:ssl_verify_ocsp_endpoint`` is set. - ``Boolean`` - true * - ``:ssl_verify_certificate`` - Whether to perform peer certificate validation. This setting overrides the ``:ssl_verify`` setting with respect to whether certificate validation is performed. - ``Boolean`` - true * - ``:ssl_verify_hostname`` - Whether to perform peer hostname validation. This setting overrides the ``:ssl_verify`` setting with respect to whether hostname validation is performed. - ``Boolean`` - true * - ``:ssl_verify_ocsp_endpoint`` - Whether to validate server-supplied certificate against the OCSP endpoint specified in the certificate, if the OCSP endpoint is specified in the certificate. This setting overrides :ssl_verify with respect to whether OCSP endpoint validation is performed. - ``Boolean`` - true * - ``:truncate_logs`` - Whether to truncate the logs at the default 250 characters. - ``Boolean`` - true * - ``:user`` - The name of the user to authenticate with. - ``String`` - none * - ``:wait_queue_timeout`` - The number of seconds to wait for a connection in the connection pool to become available. - ``Float`` - 10 * - ``:wrapping_libraries`` - Information about libraries such as ODMs that are wrapping the driver. Specify the lower level libraries first. Allowed hash keys: :name, :version, :platform. Example: ``[name: 'Mongoid', version: '7.1.2']`` - ``Array`` - none * - ``:write`` - Deprecated. Equivalent to ``:write_concern`` option. If both ``:write`` and ``:write_concern`` are specified, their values must be identical. - ``Hash`` - ``{ w: 1 }`` * - ``:write_concern`` - Specifies write concern options as a ``Hash``. Keys in the hash can be ``:w``, ``:wtimeout``, ``:j``, ``:fsync``. Note that ``:wtimeout`` is specified in milliseconds, not seconds. .. code-block:: ruby { write_concern: { w: 2 } } - ``Hash`` - ``{ w: 1 }`` * - ``:zlib_compression_level`` - The Zlib compression level to use, if using compression. See Ruby's Zlib module for valid levels. - ``Integer`` - none .. note:: The Ruby driver does not implement certificate revocation list (CRL) checking. URI Options ----------- Since the URI options are required to be in camel case, which is not the Ruby standard, the following table shows URI options and their corresponding Ruby options. URI options are explained in detail in the :manual:`Connection URI reference `. .. note:: Options that are set in **milliseconds** in the URI are represented as a ``float`` in Ruby and the units are **seconds**. .. list-table:: :header-rows: 1 :widths: 40 105 * - URI Option - Ruby Option * - appName=String - ``:app_name => String`` * - authMechanism=String - ``:auth_mech => Symbol`` Auth mechanism values are converted as follows from URI options to Ruby options: - ``GSSAPI`` => ``:gssapi`` - ``MONGODB-CR`` => ``:mongodb_cr`` - ``MONGODB-X509`` => ``:mongodb_x509`` - ``PLAIN`` => ``:plain`` - ``SCRAM-SHA-1`` => ``:scram`` - ``SCRAM-SHA-256`` => ``:scram256`` If a different value is provided for auth mechanism, it is converted to the Ruby option unmodified and retains its ``String`` type. Note that, while currently the driver allows a ``Client`` instance to be constructed with an unrecognized auth mechanism, this behavior `may change in a future version of the driver `_. * - authMechanismProperties=Strings - ``{ :auth_mech_properties => { :service_realm => String, :canonicalize_host_name => true|false, :service_name => String } }`` Specified as comma-separated key:value pairs, e.g. ``"SERVICE_REALM:foo,CANONICALIZE_HOST_NAME:TRUE"``. * - authSource=String - ``:auth_source => String`` * - compressors=Strings - ``:compressors => Array`` A comma-separated list of potential compressors to use, in order of preference. Please see below for details on how the driver implements compression. * - connect=String - ``:connect => Symbol`` The same values that the ``:connect`` Ruby option accepts are accepted here. For multi-word values, the values must be provided using underscores to separate the words, i.e. ``connect=replica_set`` and ``connect=load_balanced``. * - connectTimeoutMS=Integer - ``:connect_timeout => Float`` Unlike the corresponding Ruby option which fails client creation on invalid values (e.g. negative and non-numeric values), invalid values provided via this URI option are ignored with a warning. * - directConnection=Boolean - ``:direct_connection => Boolean`` * - fsync=Boolean - ``{ :write_concern => { :fsync => true|false }}`` * - heartbeatFrequencyMS=Integer - ``:heartbeat_frequency => Float`` * - journal=Boolean - ``{ :write_concern => { :j => true|false }}`` * - loadBalanced=Boolean - ``:load_balanced => Boolean`` * - localThresholdMS=Integer - ``:local_threshold => Float`` * - maxIdleTimeMS=Integer - ``:max_idle_time => Float`` * - maxStalenessSeconds=Integer - ``{ :read => { :max_staleness => Integer }}`` If the maxStalenessSeconds URI option value is -1, the driver treats this as if the option was not given at all. Otherwise, if the option value is numeric, the Ruby option is set to the specified value converted to an ``Integer``. Note that numeric values greater than 0 but less than 90, or less than -1, are accepted by the ``Client`` constructor but will cause server selection to fail (unless the option is changed via, for example, the ``with`` method prior to any operations being performed on the driver). If the option value is non-numeric, it is ignored and the driver treats this case as if the option was not given at all. * - maxPoolSize=Integer - ``:max_pool_size => Integer`` * - minPoolSize=Integer - ``:min_pool_size => Integer`` * - readConcernLevel=String - ``:read_concern => Hash`` * - readPreference=String - ``{ :read => { :mode => Symbol }}`` * - readPreferenceTags=Strings - ``{ :read => { :tag_sets => Array }}`` Each instance of the readPreferenceTags field is a comma-separated key:value pair which will appear in the :tag_sets array in the order they are specified. For instance, ``"readPreferenceTags=dc:ny,rack:1&readPreferenceTags=dc:ny"`` will be converted to ``[ { 'dc' => 'ny', 'rack' => '1' }, { 'dc' => 'ny' }]``. * - replicaSet=String - ``:replica_set => String`` * - retryWrites=Boolean - ``:retry_writes => boolean`` * - serverSelectionTimeoutMS=Integer - ``:server_selection_timeout => Float`` * - socketTimeoutMS=Integer - ``:socket_timeout => Float`` Unlike the corresponding Ruby option which fails client creation on invalid values (e.g. negative and non-numeric values), invalid values provided via this URI option are ignored with a warning. * - srvMaxHosts=Integer - ``:srv_max_hosts => Integer`` * - srvServiceName=String - ``:srv_service_name => String`` * - ssl=Boolean - ``:ssl => true|false`` * - tls=Boolean - ``:ssl => boolean`` * - tlsAllowInvalidCertificates=Boolean - ``:ssl_verify_certificate => boolean`` Because ``tlsAllowInvalidCertificates`` uses ``true`` to signify that verification should be disabled and ``ssl_verify_certificate`` uses ``false`` to signify that verification should be disabled, the boolean is inverted before being used to set ``ssl_verify_certificate``. * - tlsAllowInvalidHostnames=Boolean - ``:ssl_verify_hostname => boolean`` Because ``tlsAllowInvalidHostnames`` uses ``true`` to signify that verification should be disabled and ``ssl_verify_hostname`` uses ``false`` to signify that verification should be disabled, the boolean is inverted before being used to set ``ssl_verify_hostname``. * - tlsCAFile=String - ``:ssl_ca_cert => String`` * - tlsCertificateKeyFile=String - ``:ssl_cert => String`` * - tlsCertificateKeyFile=String - ``:ssl_key => String`` * - tlsCertificateKeyFilePassword=String - ``:ssl_key_pass_phrase => String`` * - tlsDisableOCSPEndpointCheck=Boolean - ``:ssl_verify_ocsp_endpoint => boolean`` Because ``tlsDisableOCSPEndpointCheck`` uses ``true`` to signify that verification should be disabled and ``ssl_verify_ocsp_endpoint`` uses ``false`` to signify that verification should be disabled, the boolean is inverted before being used to set ``ssl_verify_ocsp_endpoint``. * - tlsInsecure=Boolean - ``:ssl_verify => boolean`` Because tlsInsecure uses ``true`` to signify that verification should be disabled and ``ssl_verify`` uses ``false`` to signify that verification should be disabled, the boolean is inverted before being used to set ``ssl_verify``. * - w=Integer|String - ``{ :write_concern => { :w => Integer|String }}`` * - waitQueueTimeoutMS=Integer - ``:wait_queue_timeout => Float`` * - wtimeoutMS=Integer - ``{ :write_concern => { :wtimeout => Integer }}`` * - zlibCompressionLevel=Integer - ``:zlib_compression_level => Integer`` .. note:: The Ruby driver only fails connections when it receives a definitive signed response indicating that the server's certificate has been revoked. Because of this, the driver does not recognize the ``tlsDisableCertificateRevocationCheck`` URI option. If this option is provided in a URI, it will be ignored. Timeout Options =============== ``server_selection_timeout`` ---------------------------- When executing an operation, the number of seconds to wait for the driver to find an appropriate server to send an operation to. Defaults to 30. A value of 0 means no timeout. When an invalid value (e.g. a negative value or a non-numeric value) is passed via the URI option, the invalid input is ignored with a warning. When an invalid value is passed directly to Client via a Ruby option, Client construction fails with an error. In replica set deployments, this timeout should be set to exceed the typical :manual:`replica set election times ` in order for the driver to transparently handle primary changes. This timeout also allows the application and the database to be started simultaneously; the application will wait up to this much time for the database to become available. If the application server is behind a reverse proxy, server selection timeout should be lower than the request timeout configured on the reverse proxy (for example, this applies to deployments on Heroku which has a fixed 30 second timeout in the routing layer). In development this value can be lowered to provide quicker failure when the server is not running. ``socket_timeout`` ------------------ The number of seconds to wait for a socket read or write to complete on regular (non-monitoring) connections. Default is no timeout. A value of 0 means no timeout. When an invalid value (e.g. a negative value or a non-numeric value) is passed via the URI option, the invalid input is ignored with a warning. When an invalid value is passed directly to Client via a Ruby option, Client construction fails with an error. This timeout should take into account both network latency and operation duration. For example, setting this timeout to 5 seconds will abort queries taking more than 5 seconds to execute on the server with ``Mongo::Error::SocketTimeoutError``. Note that even though by default there is no socket timeout set, the operating system may still time out read operations depending on its configuration. The keepalive settings are intended to detect broken network connections (as opposed to aborting operations simply because they take a long time to execute). Note that if an operation is timed out by the driver due to exceeding the ``socket_timeout`` value, it is not aborted on the server. For this reason it is recommended to use ``max_time_ms`` option for potentially long running operations, as this will abort their execution on the server. This option does not apply to monitoring connections. ``connect_timeout`` ------------------- The number of seconds to wait for a socket connection to be established to a server. Defaults to 10. This timeout is also used as both connect timeout and socket timeout for monitoring connections. When using a ``mongodb+srv://`` URI, this timeout is also used for SRV and TXT DNS lookups. Note that the timeout applies per lookup; due to DNS suffix search lists, multiple lookups may be performed as part of a single name resolution. ``wait_queue_timeout`` `````````````````````` The number of seconds to wait for a connection in the connection pool to become available. Defaults to 10. As of driver version 2.11, this timeout should be set to a value at least as large as ``connect_timeout`` because connection pool now fully establishes connections prior to returning them, which may require several network round trips. ``max_time_ms`` --------------- Specified as an option on a particular operation, the number of milliseconds to allow the operation to execute for on the server. Not set by default. Consider using this option instead of a ``socket_timeout`` for potentially long running operations to be interrupted on the server when they take too long. ``wtimeout`` ------------ The number of milliseconds to wait for a write to be acknowledged by the number of servers specified in the write concern. Not set by default, which instructs the server to apply its default. This option can be set globally on the client or passed to individual operations under ``:write_concern``. TLS Connections =============== To connect to the MongoDB deployment using TLS: - Enable TLS connections in ``Mongo::Client``. - Specify the client TLS certificate. - Specify the CA certificate to verify the server's TLS certificate. .. note:: When using JRuby, ECDSA certificates are not currently supported. TLS vs SSL Option Names ----------------------- All MongoDB server versions supported by the Ruby driver (2.6 and higher) only implement TLS. 2.6 and higher servers do not use SSL. For historical reasons, the Ruby option names pertaining to TLS configuration use the ``ssl`` rather than the ``tls`` prefix. The next major version of the Ruby driver (3.0) will use the ``tls`` prefix for Ruby option names. The URI option names use the ``tls`` prefix, with one exception: there is a ``ssl`` URI option that is deprecated and equivalent to the ``tls`` URI option. Enable TLS Connections ---------------------- TLS must be explicitly requested on the client side when the deployment requires TLS connections - there is currently no automatic detection of whether the deployment requires TLS. To request TLS connections, specify the following client options when constructing a ``Mongo::Client``: - The ``:ssl`` Ruby option. - The ``tls`` URI option. - The ``ssl`` URI option (deprecated). Specify Client TLS Certificate ------------------------------ By default, MongoDB server will attempt to verify the connecting clients' TLS certificates, which requires the clients to specify their TLS certificates when connecting. This can be accomplished via: - The ``:ssl_cert``/``:ssl_cert_object``/``:ssl_cert_string`` and ``:ssl_key``/``:ssl_key_object``/``:ssl_key_string``/``:ssl_key_pass_phrase`` Ruby options. - The ``tlsCertificateKeyFile`` URI option. When using the Ruby options, the client TLS certificate and the corresponding private key may be provided separately. For example, if the certificate is stored in ``client.crt`` and the private key is stored in ``client.key``, a ``Mongo::Client`` may be constructed as follows: .. code-block:: ruby client = Mongo::Client.new(["localhost:27017"], ssl: true, ssl_cert: 'path/to/client.crt', ssl_key: 'path/to/client.key', ssl_ca_cert: 'path/to/ca.crt', ) ``ssl_cert``, ``ssl_cert_string``, ``ssl_key`` and ``ssl_key_string`` Ruby options also permit the certificate and the key to be provided in the same file or string, respectively. The files containing both certificate and private key frequently have the ``.pem`` extension. When both certificate and the private key are provided in the same file or string, both the certifcate and the key options must be utilized, as follows: .. code-block:: ruby client = Mongo::Client.new(["localhost:27017"], ssl: true, ssl_cert: 'path/to/client.pem', ssl_key: 'path/to/client.pem', ssl_ca_cert: 'path/to/ca.crt', ) When using the URI option, the certificate and the key must be stored in a file and both must be stored in the same file. Example usage: .. code-block:: ruby client = Mongo::Client.new( "mongodb://localhost:27017/?tls=true&tlsCertificateKeyFile=path%2fto%2fclient.pem&tlsCertificateKeyFile=path%2fto%2fca.crt") .. note:: URI option values must be properly URI escaped. This applies, for example, to slashes in the paths. .. _modifying-tls-context: Modifying ``SSLContext`` ------------------------ It may be desirable to further configure TLS options in the driver, for example by enabling or disabling certain ciphers. Currently, the Ruby driver does not provide a way to do this when initializing a ``Mongo::Client``. However, the Ruby driver provides a way to set global "TLS context hooks" -- these are user-provided ``Proc``s that will be invoked before any TLS socket connection and can be used to modify the underlying ``OpenSSL::SSL::SSLContext`` object used by the socket. To set the TLS context hooks, add ``Proc``s to the ``Mongo.tls_context_hooks`` array. This should be done before creating any Mongo::Client instances. For example, in a Rails application this code could be placed in an initializer. .. 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 ``Proc``s will be executed sequentially during the creation of every ``Mongo::Socket::SSL`` object. It is possible to assign the entire array of hooks calling ``Mongo.tls_context_hooks=``, but doing so will remove any previously assigned hooks. It is recommended to use the ``Array#push`` or ``Array#unshift`` methods to add new hooks. It is also possible to remove hooks from ``Mongo.tls_context_hooks`` by storing a reference to the Procs somewhere else in the application, and then using ``Array#delete_if`` to remove the desired hooks. ..warning :: TLS context hooks are global and will affect every instance of ``Mongo::Client``. Any library that allows applications to enable these hooks should expose methods to modify the hooks (which can be called by the application) rather than automatically enabling the hooks when the library is loaded. Further information on configuring MongoDB server for TLS is available in the :manual:`MongoDB manual `. Using Intermediate Certificates ``````````````````````````````` It is possible to use certificate chains for both the client and the server certificates. When using chains, the certificate authority parameter should be configured to contain the trusted root certificates only; the intermediate certificates, if any, should be provided in the server or client certificates by concatenating them after the leaf server and client certificates, respectively. ``:ssl_cert`` and ``:ssl_cert_string`` Ruby options, as well as ``tlsCertificateKeyFile`` URI option, support certificate chains. ``:ssl_cert_object`` Ruby option, which takes an instance of ``OpenSSL::X509::Certificate``, does not support certificate chains. The Ruby driver performs strict X.509 certificate verification, which requires that both of the following fields are set in the intermediate certificate(s): - X509v3 Basic Constraints: CA: TRUE -- Can sign certificates - X509v3 Key Usage: Key Cert Sign -- Can sign certificates More information about these flags can be found `in this Stack Overflow question `_. It is a common pitfall to concatenate intermediate certificates to the root CA certificates passed in ``tlsCAFile`` / ``ssl_ca_cert`` options. By doing so, the intermediate certificates are elevated to trusted status and are themselves not verified against the actual CA root. More information on this issue is available `in this mailing list post `_. Specify CA Certificate ---------------------- The driver will attempt to verify the server's TLS certificate by default, and will abort the connection if this verification fails. By default, the driver will use the default system root certificate store as the trust anchor. To specify the CA certificate that the server's certificate is signed with, use: - The ``:ssl_ca_cert``/``:ssl_ca_cert_string``/``:ssl_ca_cert_object`` Ruby options - The ``tlsCAFile`` URI option. If any of these options are given, the server's certificate will be verified only against the specified CA certificate and the default system root certificate store will not be used. To not perform server TLS certificate verification, which is not recommended, specify the ``ssl_verify: false`` Ruby option or the ``tlsInsecure=true`` URI option. Specifying Multiple CA Certificates ``````````````````````````````````` The ``:ssl_ca_cert`` Ruby option and ``tlsCAFile`` URI option can be used with a file containing multiple certificates. All certificates thus referenced will become trust anchors. The ``:ssl_ca_cert_object`` option takes an array of certificates, and thus can also be used to add multiple certificates as certificate authorities. The ``:ssl_ca_cert_string`` option supports specifying only one CA certificate. .. warning:: Intermediate certificates must not be provided in files specified by the CA certificate options. Doing so would elevate the intermediate certificates to the status of root certificates, rather than verifying intermediate certificates against the root certificates. If intermediate certificates need to be used, specify them as part of the client or server TLS certificate files. .. _ocsp-verification: OCSP Verification ----------------- If the certificate provided by the server contains an OCSP endpoint URI, the driver will issue an OCSP request to the specified endpoint to verify the validity of the certificate. The OCSP endpoint check may be disabled by setting the ``:ssl_verify_ocsp_endpoint`` Ruby option to ``false`` or by setting the ``tlsDisableOCSPEndpointCheck`` URI option to ``true`` when creating a client. .. note:: OCSP endpoint checking is not currently performed when running on JRuby, since JRuby does not correctly expose the OCSP endpoint URI. IPv4/IPv6 Connections ===================== When a client is constructed with ``localhost`` as the host name, it will attempt an IPv4 connection only (i.e. if ``localhost`` resolves to ``127.0.0.1`` and ``::1``, the driver will only try to connect to ``127.0.0.1``). When a client is constructed with hostnames other than ``localhost``, it will attempt both IPv4 and IPv6 connections depending on the addresses that the hostnames resolve to. The driver respects the order in which ``getaddrinfo`` returns the addresses, and will attempt to connect to them sequentially. The first successful connection will be used. The driver does not currently implement the Happy Eyeballs algorithm. TCP Keepalive Configuration =========================== Where allowed by system configuration and the Ruby language runtime, the driver enables TCP keepalive and, for each of the keepalive parameters listed below, sets the value of the respective parameter to the specified value if the system value can be determined and is higher than the listed driver value: - ``tcp_keepalive_time``: 120 seconds - ``tcp_keepalive_intvl``: 10 seconds - ``tcp_keepalive_cnt``: 9 probes .. note:: As of JRuby 9.2.14.0, JRuby does not implement the APIs required to set the keepalive parameters. When using JRuby, the driver will not be able to set the keepalive parameters and the system configuration will be in effect. To use lower values, or to change the parameters in environments like JRuby that do not expose the required APIs, please adjust the parameters at the system level as described in the `MongoDB Diagnostics FAQ keepalive section `_. Connection Pooling ================== ``Mongo::Client`` instances have a connection pool per server that the client is connected to. The pool creates connections on demand to support concurrent MongoDB operations issued by the application. There is no thread-affinity for connections. The client instance opens one additional connection per known server for monitoring the server's state. The size of each connection pool is capped at ``max_pool_size``, which defaults to 5. When a thread in the application begins an operation on MongoDB, it tries to retrieve a connection from the pool to send that operation on. If there are some connections available in the pool, it checks out a connection from the pool and uses it for the operation. If there are no connections available and the size of the pool is less than the ``max_pool_size``, a new connection will be created. If all connections are in use and the pool has reached its maximum size, the thread waits for a connection to be returned to the pool by another thread. If ``max_pool_size`` is set to zero, there is no limit for the maximum number of connections in the pool. The number of seconds the thread will wait for a connection to become available is configurable. This setting, called ``wait_queue_timeout``, is defined in seconds. If this timeout is reached, a ``Timeout::Error`` is raised. The default is 1 second. As of driver version 2.11, the driver eagerly creates connections up to ``min_pool_size`` setting. Prior to driver version 2.11, the driver always created connections on demand. In all versions of the driver, once a connection is established, it will be kept in the pool by the driver as long as the pool size does not exceed ``min_pool_size``. Note that, if ``min_pool_size`` is set to a value greater than zero, the driver will establish that many connections to secondaries in replica set deployments even if the application does not perform secondary reads. The purpose of these connections is to provide faster failover when the primary changes. Here is an example of estimating the number of connections a multi-threaded application will open: A client connected to a 3-node replica set opens 3 monitoring sockets. It also opens as many sockets as needed to support a multi-threaded application's concurrent operations on each server, up to ``max_pool_size``. If the application only uses the primary (the default), then only the primary connection pool grows and the total connections is at most 8 (5 connections for the primary pool + 3 monitoring connections). If the application uses a read preference to query the secondaries, their pools also grow and the total connections can reach 18 (5 + 5 + 5 + 3). The default configuration for a ``Mongo::Client`` works for most applications: .. code-block:: ruby client = Mongo::Client.new(["localhost:27017"]) Create this client **once** for each process, and reuse it for all operations. It is a common mistake to create a new client for each request, which is very inefficient and not what the client was designed for. To support extremely high numbers of concurrent MongoDB operations within one process, increase ``max_pool_size``: .. code-block:: ruby client = Mongo::Client.new(["localhost:27017"], max_pool_size: 200) Any number of threads are allowed to wait for connections to become available, and they can wait the default (1 second) or the ``wait_queue_timeout`` setting: .. code-block:: ruby client = Mongo::Client.new(["localhost:27017"], wait_queue_timeout: 0.5) When ``#close`` is called on a client by any thread, all connections are closed: .. code-block:: ruby client.close Note that when creating a client using the `block syntax <#block-syntax>`_ described above, the client is automatically closed after the block finishes executing. .. _forking: Usage with Forking Servers ========================== .. note:: Applications using Mongoid should follow `Mongoid's forking guidance `_. The guidance and sample code below is provided for applications using the Ruby driver directly. When using the Mongo Ruby driver in a Web application with a forking web server such as Unicorn, Puma or Passenger, or when the application otherwise forks, each process should generally each have their own ``Mongo::Client`` instances. This is because: 1. The background threads remain in the parent process and are not transfered to the child process. 2. File descriptors like network sockets are shared between parent and child processes. The driver attempts to detect client use from forked processes and reestablish network connections when such use is detected, alleviating the issue of file descriptor sharing. If both parent and child processes need to perform MongoDB operations, it is recommended for each of the processes to create their own ``Mongo::Client`` instances. Specifically, the child process should create its own client instance and not use any of the instances that were created in the parent. If the parent continues to perform MongoDB operations using an already established client instance after forking children, this client instance will continue to operate normally as long as no child uses it in any way. The child processes will not inherit any of the monitoring threads, and will not perform background operations on the client instance. If the parent does not need to perform MongoDB operation after forking children (which is what typically happens in web applications), the parent should close all of the client instances it created to free up connections and cease background monitoring: .. code-block:: ruby client.reconnect .. note:: If the parent process performs operations on the 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. Reconnecting Client Instances ----------------------------- When the Ruby driver is used in a web application, it is recommended to not create any ``Mongo::Client`` instances in the management processes (prior to the workers being forked), and instead only create client instances in the workers. It is possible, although not recommended, to use the same ``Mongo::Client`` instances in parent and child processes. In order to do so, the instance must be closed and reconnected in the child process so that the background threads can be recreated: .. code-block:: ruby client.close client.reconnect .. note:: This pattern should be used with Ruby driver version 2.6.2 or higher. Previous driver versions did not recreate monitoring threads when reconnecting. .. note:: When closing and reconnecting the client instance in the child, due to file descriptor sharing, the parent process may experience network and monitoring errors. Web servers generally provide hooks that can be used by applications to perform actions when the worker processes are forked. The recommended hooks to use are: - For `Puma `_, ``before_fork`` to close clients in the parent process and ``on_worker_boot`` to reconnect in the child processes. - For `Unicorn `_, ``before_fork`` to close clients in the parent process and ``after_fork`` to reconnect clients in the child processes. - For `Passenger `_, ``starting_worker_process`` to reconnect clients in the child processes (Passenger does not appear to have a pre-fork hook). This documentation does not provide example code for using the aforementioned hooks, because there is no standard for client instance management when using the Ruby driver directly. `Mongoid documentation `_ however provides examples for closing clients in the parent process and reconnecting clients in the child processes. Troubleshooting --------------- The client's ``summary`` method returns the current state of the client, including servers that the client is monitoring and their state. If any of the servers are not being monitored, this is indicated by the ``NO-MONITORING`` flag. A normally operating client will produce a summary similar to the following: .. code-block:: ruby client.summary => "#>, #>, #>, #]>>" A client that is missing background threads will produce a summary similar to the following: .. code-block:: ruby client.summary => "#>, #>, #>, #]>>" Retryable Reads =============== The driver implements two mechanisms for retrying reads: modern and legacy. As of driver version 2.9.0, the modern mechanism is used by default, and the legacy mechanism is deprecated. Modern Retryable Reads ---------------------- When the modern mechanism is used, read operations are retried once in the event of a network error, a "not master" error, or a "node is recovering" error. The following operations are covered: - `Collection#find `_ and related methods - `Collection#aggregate `_ - `Collection#count `_, `Collection#count_documents `_ - Change stream helpers: `Collection#watch `_, `Database#watch `_, `Client#watch `_ - Enumeration commands: `Client#list_mongo_databases `_, `Client#list_databases `_, `Client#database_names `_, `Database#collection_names `_, `Database#collections `_, `Database#list_collections `_, `Collection#indexes `_ When an operation returns a cursor, only the initial read command can be retried. ``getMore`` operations on cursors are not retried by driver version 2.9.0 or newer. Additionally, when a read operation is retried, a new server for the operation is selected; this may result in the retry being sent to a different server from the one which received the first read. The behavior of modern retryable reads is covered in detail by the `retryable reads specification `_. Note that the modern retryable reads can only be used with MongoDB 3.6 and higher servers. When used with MongoDB 3.4 and lower servers, Ruby driver version 2.9.0 and higher will not retry reads by default - the application must explicitly request legacy retryable reads by setting the ``retry_reads: false`` client option or using ``retryReads=false`` URI option. Legacy Retryable Reads ---------------------- The legacy read retry behavior of the Ruby driver is available by setting the ``retry_reads: false`` client option or passing the ``retryReads=false`` URI option to the client. When using legacy read retry behavior, the number of retries can be set by specifying the ``max_read_retries`` client option. When using driver version 2.9.0 or higher, the set of operations which would be retried with legacy retryable reads is identical to the one described above for modern retryable reads. In older driver versions the behavior of legacy retryable writes was different in that some of the operations were not retried. As of driver version 2.9.0, legacy read retries perform server selection prior to retrying the operation, as modern retriable writes do. In older driver versions read retries would be sent to the same server which the initial read was sent to. Disabling Retryable Reads ------------------------- To disable all read retries, set the following client options: ``retry_reads: false, max_read_retries: 0``. Retryable Writes ================ The driver implements two mechanisms for retrying writes: modern and legacy. As of driver version 2.9.0, the modern mechanism is used by default on servers that support it, and the legacy mechanism is deprecated and disabled by default on all server versions. The following write methods used in day-to-day operations on collections are subject to write retries: - ``collection#insert_one`` - ``collection#update_one`` - ``collection#delete_one`` - ``collection#replace_one`` - ``collection#find_one_and_update`` - ``collection#find_one_and_replace`` - ``collection#find_one_and_delete`` - ``collection#bulk_write`` (for all single statement ops, i.e. not for ``update_many`` or ``delete_many``) Modern Retryable Writes ----------------------- The modern mechanism will retry failing writes once when the driver is connected to a MongoDB 3.6 or higher replica set or a sharded cluster, because they require an oplog on the serer. Modern mechanism will not retry writes when the driver is connected to a standalone MongoDB server or server versions 3.4 or older. The following errors will cause writes to be retried: - Network errors including timeouts - "not master" errors - "node is recovering" errors Prior to retrying the write the driver will perform server selection, since the server that the original write was sent to is likely no longer usable. Legacy Retryable Writes ----------------------- If modern retryable writes mechanism is disabled by setting the client option ``retry_writes: false`` or by using the ``retryWrites=false`` URI option, the driver will utilize the legacy retryable writes mechanism. The legacy mechanism retries writes on the same operations as the modern mechanism. By default the legacy mechanism retries once, like the modern mechanism does; to change the number of retries, set ``:max_write_retries`` client option. The difference between legacy and modern retry mechanisms is that the legacy mechanism retries writes for a different set of errors compared to the modern mechanism, and specifically does not retry writes when a network timeout is encountered. Disabling Retryable Writes -------------------------- To disable all write retries, set the following client options: ``retry_writes: false, max_write_retries: 0``. Logging ======= You can either use the default global driver logger or set your own. To set your own: .. code-block:: ruby Mongo::Logger.logger = other_logger See the `Ruby Logger documentation `_ for more information on the default logger API and available levels. Changing the Logger Level ------------------------- To change the logger level: .. code-block:: ruby Mongo::Logger.logger.level = Logger::WARN For more control, a logger can be passed to a client for per-client control over logging. .. code-block:: ruby my_logger = Logger.new(STDOUT) Mongo::Client.new([ '127.0.0.1:27017' ], :database => 'test', :logger => my_logger ) Truncation ---------- The default logging truncates logs at 250 characters by default. To turn this off pass an option to the client instance. .. code-block:: ruby Mongo::Client.new([ '127.0.0.1:27017' ], :database => 'test', :truncate_logs => false ) .. _compression: Compression =========== To use wire protocol compression, at least one compressor must be explicitly requested using either the ``:compressors`` Ruby option or the ``compressors`` URI option. If no compressors are explicitly requested, the driver will not use compression, even if the required dependencies for one or more compressors are present on the system. The driver chooses the first compressor of the ones requested that is also supported by the server. The driver currently supports ``zstd``, ``snappy`` and ``zlib`` compressors. ``zstd`` compressor is recommended as it produces the highest compression at the same CPU consumption compared to the other compressors. For maximum server compatibility all three compressors can be specified, e.g. as ``compressors: ["zstd", "snappy", "zlib"]``. ``zstd`` compressor requires the `zstd-ruby `_ library to be installed. ``snappy`` compressor requires the `snappy `_ library to be installed. If ``zstd`` or ``snappy`` compression is requested, and the respective library is not loadable, the driver will raise an error during ``Mongo::Client`` creation. ``zlib`` compression requires the ``zlib`` standard library extension to be present. The server support for various compressors is as follows: - ``zstd`` requires and is enabled by default in MongoDB 4.2 or higher. - ``snappy`` requires MongoDB 3.4 or higher and is enabled by default in MongoDB 3.6 or higher. - ``zlib`` requires MongoDB 3.6 or higher and is enabled by default in MongoDB 4.2 and higher. .. _server-api-parameters: Server API Parameters ===================== Starting with MongoDB 5.0, applications can request that the server behaves in accordance with a particular server API version. Server API parameters can be specified via the ``:server_api`` option to ``Client``. These parameters cannot be provided via a URI. Currently the only defined API version is ``"1"``. It can be requested as follows: .. code-block:: ruby client = Mongo::Client.new(['localhost'], server_api: {version: "1"}) MongoDB server defines API versions as string values. For convenience, if the API version is provided as an integer, the Ruby driver will stringify it and send it to the server as a string: .. code-block:: ruby client = Mongo::Client.new(['localhost'], server_api: {version: 1}) Note that the server may define API versions that are not stringified integers. Applications must not assume that all legal API versions can be expressed as integers. When a particular API version is requested, operations which are part of that API version behave as specified in that API version. Operations which are not part of the specified API version behave as they would had the API version not been specified at all. Operations whose behavior is subject to the configured API version are commands including command arguments, queries, aggregation pipeline stages and arguments. Applications may request that the server rejects all operations which are not part of the specified API version by setting the ``:strict`` option: .. code-block:: ruby client = Mongo::Client.new(['localhost'], server_api: {version: "1", strict: true}) For example, since the ``:tailable`` option is not part of the server API version 1, the following query would fail: .. code-block:: ruby client = Mongo::Client.new(['localhost'], server_api: {version: "1", strict: true}) client['collection'].find({}, tailable: true) # => Mongo::Error::OperationFailure (BSON field 'FindCommand.tailable' is not allowed with apiStrict:true. (323) (on localhost:27017, modern retry, attempt 1)) Applications may request that the server rejects all operations which are deprecated in the specified API version by setting the ``:deprecation_errors`` option: .. code-block:: ruby client = Mongo::Client.new(['localhost'], server_api: {version: "1", deprecation_errors: true}) Note that, as of this writing, there are no deprecated operations in API version ``"1"``. If the server API parameters have been defined on a ``Client`` object, they will be sent by the client as part of each [*]_ executed operation. .. [*] ``getMore`` commands and commands in transactions do not accept API parameters, thus the driver will not send them in these cases. MongoDB servers prior to 5.0 do not recognize the API parameters, and will produce a variety of errors should the application configure them. The Ruby driver will send the API parameters to all MongoDB 3.6 and newer servers, but the API parameters should only be configured when the application is communicating with MongoDB 5.0 or newer servers. The API parameters cannot be sent to MongoDB 3.4 and older servers that use the legacy wire protocol; if an application configures the API parameters and connects to MongoDB 3.4 or older servers, the driver will produce an error on every operation. The :ref:`command helper ` permits the application to send manually constructed commands to the server. If the client is not configured with server API parameters, the command helper may be used to issue commands with API parameters: .. code-block:: ruby client.database.command( ping: 1, apiVersion: "1", apiStrict: false, apiDeprecationErrors: false, ) If the client is configured with server API parameters, the command helper may not be used to issue commands with server API parameters. This includes the case when the server API parameters provided to the client and to the command helper are identical. If a client is constructed with server API parameters, to send different API parameters (or none at all) a new client must be constructed, either from scratch or using the ``with`` method. The server API parameters may only be specified on the client level. They may not be specified on the database, collection, session, transaction or individual operation level. 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. Production Configuration ======================== Please consider the following when deploying an application using the Ruby driver in production: - As of driver version 2.11, the ``:min_pool_size`` client option is completely respected - the driver will create that many connections to each server identified as a standalone, primary or secondary. In previous driver versions the driver created connections on demand. Applications using ``:min_pool_size`` will see an increase in the number of idle connections to all servers as of driver version 2.11, and especially to secondaries in replica set deployments and to nodes in sharded clusters. - If the application is reverse proxied to by another web server or a load balancer, ``server_selection_timeout`` should generally be set to a lower value than the reverse proxy's read timeout. For exampe, `Heroku request timeout `_ is 30 seconds and is not configurable; if deploying a Ruby application using MongoDB to Heroku, consider lowering server selection timeout to 20 or 15 seconds. .. _feature-flags: Feature Flags ============= The following is a list of feature flags that the Mongo Ruby Driver provides: .. list-table:: :header-rows: 1 :widths: 30 60 * - Flag - Description * - ``broken_view_aggregate`` - When this flag is off, an aggregation done on a view will be executed over the documents included in that view, instead of all documents in the collection. When this flag is on, the view fiter is ignored and the aggregation is applied over all of the documents in the view's collection. (default: true) * - ``broken_view_options`` - When this flag is turned off, the view options will be correctly propagated to the ``aggregate``, ``count``, ``count_documents``, ``distinct``, and ``estimated_document_count`` mehods. When this flag is switched on, the view options will be ignored in those methods. (default: true) * - ``validate_update_replace`` - 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. (default: false) These feature flags can be set directly on the ``Mongo`` module or using the ``options`` method: .. code:: Mongo.validate_update_replace = true Mongo.options = { validate_update_replace: true }