Creating a Client
On this page
- Using
Mongo::Client
- Block Syntax
- Database Selection
- Connection Types
- Standalone Server Connection
- Replica Set Connection
- Sharded Cluster Connection
- Direct Connection
- Load Balancer Connection
- MongoDB Atlas Connection
- Connect to MongoDB Atlas from AWS Lambda
- SRV URI Notes
- Client Options
- Ruby Options
- URI Options
- Timeout Options
server_selection_timeout
socket_timeout
connect_timeout
max_time_ms
wtimeout
- TLS Connections
- TLS vs SSL Option Names
- Enable TLS Connections
- Specify Client TLS Certificate
- Modifying
SSLContext
- Specify CA Certificate
- OCSP Verification
- IPv4/IPv6 Connections
- TCP Keepalive Configuration
- Connection Pooling
- Usage with Forking Servers
- Manually Handling Process Forks
- Troubleshooting
- Retryable Reads
- Modern Retryable Reads
- Legacy Retryable Reads
- Disabling Retryable Reads
- Retryable Writes
- Modern Retryable Writes
- Legacy Retryable Writes
- Disabling Retryable Writes
- Logging
- Changing the Logger Level
- Truncation
- Compression
- Server API Parameters
- Development Configuration
- Production Configuration
- Feature Flags
Using Mongo::Client
To connect to a MongoDB deployment, create a Mongo::Client
object.
Provide a list of hosts and options or a 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:
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:
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:
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
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:
# 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:
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:
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 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 direct connection section below.
Replica Set Connection
When connecting to a 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:
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:
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:
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:
Mongo::Client.new("mongodb+srv://username:myRealPassword@cluster0.mongodb.net/test?w=majority")
Please review the SRV URI notes if using SRV URIs.
Sharded Cluster Connection
To connect to a sharded cluster deployment, specify
the addresses of the mongos
routers:
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:
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:
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 SRV URI notes if using SRV URIs.
Direct Connection
To disable the deployment type discovery and force all operations to be
performed on a particular server, specify the direct_connection
option:
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:
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
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:
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:
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")
MongoDB Atlas Connection
To connect to a MongoDB deployment on Atlas, first create a Mongo::Client
instance using your
cluster's connection string and other client options.
You can set the Stable API version as a client option to avoid breaking changes when you upgrade to a new server version.
The following code shows how you can specify the connection string and the Stable API client option when connecting to a MongoDB deployment and verify that the connection is successful:
require 'mongo' # Replace the placeholders with your credentials uri = "mongodb+srv://<username>:<password>@cluster0.sample.mongodb.net/?retryWrites=true&w=majority" # Set the server_api field of the options object to Stable API version 1 options = { server_api: { version: "1" } } # Create a new client and connect to the server client = Mongo::Client.new(uri, options) # Send a ping to confirm a successful connection begin admin_client = client.use('admin') result = admin_client.database.command(ping: 1).documents.first puts "Pinged your deployment. You successfully connected to MongoDB!" rescue Mongo::Error::OperationFailure => ex puts ex ensure client.close end
Connect to MongoDB Atlas from AWS Lambda
To learn how to connect to Atlas from AWS Lambda, see the Manage Connections with AWS Lambda documentation.
SRV URI Notes
When the driver connects to a mongodb+srv protocol URI, keep in mind the following:
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.
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.
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:
Mongo::Client.new("mongodb+srv://username:myRealPassword@cluster0.mongodb.net/test?w=majority&authSource=admin") 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
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.
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
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
For more information about formatting these options, see the "Auto-Encryption Options" section of the 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<String> | 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_connecting | The maximum number of connections that the connection pool will try to establish in parallel. | Integer | 2 | ||||||
: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
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 | Hash | { :mode => :primary } | ||||||
:read_concern | Specifies the read concern options. The only valid key is level ,
for which the valid values are :local , :available , :majority ,
:snapshot , and :linearizable . | 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 Pass a Note: the client is not fully constructed when the | Proc | none | ||||||
:server_api | The server API version requested.
This is a hash with the following allowed items:
- 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 | 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 This option, if present, takes precedence over | 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 This option, if present, takes precedence over the | 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<Hash> | 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 | { 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 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.
URI Option | Ruby Option |
---|---|
appName=String | :app_name => String |
authMechanism=String |
Auth mechanism values are converted as follows from URI options to Ruby options:
If a different value is provided for auth mechanism, it is converted
to the Ruby option unmodified and retains its |
authMechanismProperties=Strings |
Specified as comma-separated key:value pairs, e.g. |
authSource=String | :auth_source => String |
compressors=Strings |
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 |
The same values that the |
connectTimeoutMS=Integer |
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 |
maxConnecting=Integer | :max_connecting => Integer |
maxIdleTimeMS=Integer | :max_idle_time => Float |
maxStalenessSeconds=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 |
maxPoolSize=Integer | :max_pool_size => Integer |
minPoolSize=Integer | :min_pool_size => Integer |
readConcernLevel=String | :read_concern => Hash |
readPreference=String | { :read => { :mode => Symbol }} |
readPreferenceTags=Strings |
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, |
replicaSet=String | :replica_set => String |
retryWrites=Boolean | :retry_writes => boolean |
serverSelectionTimeoutMS=Integer | :server_selection_timeout => Float |
socketTimeoutMS=Integer |
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 |
Because |
tlsAllowInvalidHostnames=Boolean |
Because |
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 |
Because |
tlsInsecure=Boolean |
Because tlsInsecure uses |
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 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:
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:
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:
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 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.
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 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 optionsThe
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
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 secondstcp_keepalive_intvl
: 10 secondstcp_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.
Each pool has a limit on the number of connections that can be concurrently
connecting to a server. This limit is called max_connecting
and defaults to
2. If the number of connections that are currently connecting to a server
reaches this limit, the pool will wait for a connection attempt to succeed or
fail before attempting to create a new connection. If your application
has a large number of threads, you may want to increase max_connecting
to avoid
having threads wait for a connection to be established.
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:
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
:
client = Mongo::Client.new(["localhost:27017"], max_pool_size: 200)
To support extremely high numbers of threads that share the same client
within one process, increase max_connecting
:
client = Mongo::Client.new(["localhost:27017"], max_pool_size: 200, max_connecting: 10)
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:
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:
client.close
Note that when creating a client using the block syntax described above, the client is automatically closed after the block finishes executing.
Usage with Forking Servers
Note
Applications using Mongoid should follow Mongoid's "Usage with Forking Servers" documentation. The guidance 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 Puma, or when the application otherwise forks, each process (parent and child) must have its own client connections. This is because:
Background Ruby threads, such as those used by the Ruby MongoDB driver to monitor connection state, are not transferred to the child process.
File descriptors like network sockets are shared between parent and child processes, which can cause I/O conflicts.
Regarding (1), if you do not restart the driver's monitoring threads
on the child process after forking, although your child may initially
appear to function correctly, you will eventually see
Mongo::Error::NoServerAvailable
exceptions if/when your MongoDB cluster
state changes, for example due to network errors or a maintenance event.
Regarding (2), if a child process reuses the parent's file descriptors, you
will see Mongo::Error::SocketError
errors with messages such as
Errno::EPIPE: Broken pipe
and EOFError: end of file reached
.
When the Ruby driver is used in a web application, if possible,
we recommend to not create any Mongo::Client
instances in the parent
process (prior to the workers being forked), and instead only create client
instances in the workers.
Manually Handling Process Forks
Certain advanced use cases, such as Puma's fork_worker option,
require Mongo::Client
instances to be open in both the parent
and child processes. In this case, you must handle client
reconnection manually.
To do this, immediately before forking, close any existing client connections on your parent process. This will prevent the parent process from experiencing network and monitoring errors due to the child's reuse of the parent's file descriptors.
# Immediately before fork client.close
Note
Calling Client#close
does not disrupt database operations currently in-flight.
Clients will automatically reconnect when you perform new operations.
Then, immediately after forking, reconnect your clients in the newly forked child process, which will respawn the driver's monitoring threads.
# Immediately after fork client.reconnect
Most web servers provide hooks that can be used by applications to perform actions when the worker processes are forked. The recommended hooks are:
For Puma, use
before_fork
andon_refork
to close clients in the parent process andon_worker_boot
to reconnect in the child processes.For Unicorn,
before_fork
to close clients in the parent process andafter_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).
Refer to Mongoid's "Usage with Forking Servers" documentation for further examples.
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:
client.summary => "#<Client cluster=#<Cluster topology=ReplicaSetWithPrimary[localhost:14420,localhost:14421,localhost:14422,localhost:14423,name=ruby-driver-rs,v=1,e=7fffffff000000000000001f] servers=[#<Server address=localhost:14420 PRIMARY replica_set=ruby-driver-rs pool=#<ConnectionPool size=0 (0-5) used=0 avail=0 pending=0>>, #<Server address=localhost:14421 SECONDARY replica_set=ruby-driver-rs pool=#<ConnectionPool size=0 (0-5) used=0 avail=0 pending=0>>, #<Server address=localhost:14422 SECONDARY replica_set=ruby-driver-rs pool=#<ConnectionPool size=0 (0-5) used=0 avail=0 pending=0>>, #<Server address=localhost:14423 ARBITER replica_set=ruby-driver-rs>]>>"
A client that is missing background threads will produce a summary similar to the following:
client.summary => "#<Client cluster=#<Cluster topology=ReplicaSetWithPrimary[localhost:14420,localhost:14421,localhost:14422,localhost:14423,name=ruby-driver-rs,v=1,e=7fffffff000000000000001f] servers=[#<Server address=localhost:14420 PRIMARY replica_set=ruby-driver-rs NO-MONITORING pool=#<ConnectionPool size=0 (0-5) used=0 avail=0 pending=0>>, #<Server address=localhost:14421 SECONDARY replica_set=ruby-driver-rs NO-MONITORING pool=#<ConnectionPool size=0 (0-5) used=0 avail=0 pending=0>>, #<Server address=localhost:14422 SECONDARY replica_set=ruby-driver-rs NO-MONITORING pool=#<ConnectionPool size=0 (0-5) used=0 avail=0 pending=0>>, #<Server address=localhost:14423 ARBITER replica_set=ruby-driver-rs>]>>"
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
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 forupdate_many
ordelete_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:
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:
Mongo::Logger.logger.level = Logger::WARN
For more control, a logger can be passed to a client for per-client control over logging.
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.
Mongo::Client.new([ '127.0.0.1:27017' ], :database => 'test', :truncate_logs => false )
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
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:
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:
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:
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:
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:
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 [10] executed operation.
[1] | 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 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:
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
The following is a list of feature flags that the Mongo Ruby Driver provides:
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:
Mongo.validate_update_replace = true Mongo.options = { validate_update_replace: true }