Connections
You can connect to MongoDB with the mongoose.connect()
method.
mongoose.connect('mongodb://localhost/myapp');
This is the minimum needed to connect the myapp
database running locally
on the default port (27017). If the local connection fails then try using
127.0.0.1 instead of localhost. Sometimes issues may arise when the local
hostname has been changed.
You can also specify several more parameters in the uri
:
mongoose.connect('mongodb://username:password@host:port/database?options...');
See the mongodb connection string spec for more detail.
Operation Buffering
Mongoose lets you start using your models immediately, without waiting for mongoose to establish a connection to MongoDB.
mongoose.connect('mongodb://localhost/myapp');
var MyModel = mongoose.model('Test', new Schema({ name: String }));
// Works
MyModel.findOne(function(error, result) { /* ... */ });
That's because mongoose buffers model function calls internally. This buffering is convenient, but also a common source of confusion. Mongoose will not throw any errors by default if you use a model without connecting.
var MyModel = mongoose.model('Test', new Schema({ name: String }));
// Will just hang until mongoose successfully connects
MyModel.findOne(function(error, result) { /* ... */ });
setTimeout(function() {
mongoose.connect('mongodb://localhost/myapp');
}, 60000);
To disable buffering, turn off the bufferCommands
option on your schema.
If you have bufferCommands
on and your connection is hanging, try turning
bufferCommands
off to see if you haven't opened a connection properly.
You can also disable bufferCommands
globally:
mongoose.set('bufferCommands', false);
Options
The connect
method also accepts an options
object which will be passed
on to the underlying MongoDB driver.
mongoose.connect(uri, options);
A full list of options can be found on the MongoDB Node.js driver docs for connect()
.
Mongoose passes options to the driver without modification, modulo a few
exceptions that are explained below.
bufferCommands
- This is a mongoose-specific option (not passed to the MongoDB driver) that disables mongoose's buffering mechanismuser
/pass
- The username and password for authentication. These options are mongoose-specific, they are equivalent to the MongoDB driver'sauth.user
andauth.password
options.autoIndex
- By default, mongoose will automatically build indexes defined in your schema when it connects. This is great for development, but not ideal for large production deployments, because index builds can cause performance degradation. If you setautoIndex
to false, mongoose will not automatically build indexes for any model associated with this connection.dbName
- Specifies which database to connect to and overrides any database specified in the connection string. If you're using themongodb+srv
syntax to connect to MongoDB Atlas, you should usedbName
to specify the database because you currently cannot in the connection string.
Below are some of the options that are important for tuning mongoose.
autoReconnect
- The underlying MongoDB driver will automatically try to reconnect when it loses connection to MongoDB. Unless you are an extremely advanced user that wants to manage their own connection pool, do not set this option tofalse
.reconnectTries
- If you're connected to a single server or mongos proxy (as opposed to a replica set), the MongoDB driver will try to reconnect everyreconnectInterval
milliseconds forreconnectTries
times, and give up afterward. When the driver gives up, the mongoose connection emits areconnectFailed
event. This option does nothing for replica set connections.reconnectInterval
- SeereconnectTries
promiseLibrary
- sets the underlying driver's promise librarypoolSize
- The maximum number of sockets the MongoDB driver will keep open for this connection. By default,poolSize
is 5. Keep in mind that, as of MongoDB 3.4, MongoDB only allows one operation per socket at a time, so you may want to increase this if you find you have a few slow queries that are blocking faster queries from proceeding.bufferMaxEntries
- The MongoDB driver also has its own buffering mechanism that kicks in when the driver is disconnected. Set this option to 0 and setbufferCommands
tofalse
on your schemas if you want your database operations to fail immediately when the driver is not connected, as opposed to waiting for reconnection.
Example:
const options = {
useMongoClient: true,
autoIndex: false, // Don't build indexes
reconnectTries: Number.MAX_VALUE, // Never stop trying to reconnect
reconnectInterval: 500, // Reconnect every 500ms
poolSize: 10, // Maintain up to 10 socket connections
// If not connected, return errors immediately rather than waiting for reconnect
bufferMaxEntries: 0
};
mongoose.connect(uri, options);
Callback
The connect()
function also accepts a callback parameter and returns a
promise.
mongoose.connect(uri, options, function(error) {
// Check error in initial connection. There is no 2nd param to the callback.
});
// Or using promises
mongoose.connect(uri, options).then(
() => { /** ready to use. The `mongoose.connect()` promise resolves to undefined. */ },
err => { /** handle initial connection error */ }
);
Connection String Options
You can also specify driver options in your connection string as
parameters in the query string
portion of the URI. This only applies to options passed to the MongoDB
driver. You can't set Mongoose-specific options like bufferCommands
in the query string.
mongoose.connect('mongodb://localhost:27017/test?connectTimeoutMS=1000&bufferCommands=false');
// The above is equivalent to:
mongoose.connect('mongodb://localhost:27017/test', {
connectTimeoutMS: 1000
// Note that mongoose will **not** pull `bufferCommands` from the query string
});
The disadvantage of putting options in the query string is that query
string options are harder to read. The advantage is that you only need a
single configuration option, the URI, rather than separate options for
socketTimeoutMS
, connectTimeoutMS
, etc. Best practice is to put options
that likely differ between development and production, like replicaSet
or ssl
, in the connection string, and options that should remain constant,
like connectTimeoutMS
or poolSize
, in the options object.
The MongoDB docs have a full list of supported connection string options
A note about keepAlive
For long running applications, it is often prudent to enable keepAlive
with a number of milliseconds. Without it, after some period of time
you may start to see "connection closed"
errors for what seems like
no reason. If so, after
reading this,
you may decide to enable keepAlive
:
mongoose.connect(uri, { keepAlive: 120 });
Replica Set Connections
To connect to a replica set you pass a comma delimited list of hosts to connect to rather than a single host.
mongoose.connect('mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]' [, options]);
To connect to a single node replica set, specify the replicaSet
option.
mongoose.connect('mongodb://host1:port1/?replicaSet=rsName');
Multi-mongos support
You can also connect to multiple mongos instances for high availability in a sharded cluster. You do not need to pass any special options to connect to multiple mongos in mongoose 5.x.
// Connect to 2 mongos servers
mongoose.connect('mongodb://mongosA:27501,mongosB:27501', cb);
Multiple connections
So far we've seen how to connect to MongoDB using Mongoose's default
connection. At times we may need multiple connections open to Mongo, each
with different read/write settings, or maybe just to different databases for
example. In these cases we can utilize mongoose.createConnection()
which
accepts all the arguments already discussed and returns a fresh connection
for you.
const conn = mongoose.createConnection('mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]', options);
This connection object is then used to create and retrieve models. Models are always scoped to a single connection.
Mongoose creates a default connection when you call mongoose.connect()
.
You can access the default connection using mongoose.connection
.
Connection pools
Each connection
, whether created with mongoose.connect
or
mongoose.createConnection
are all backed by an internal configurable
connection pool defaulting to a maximum size of 5. Adjust the pool size
using your connection options:
// With object options
mongoose.createConnection(uri, { poolSize: 4 });
const uri = 'mongodb://localhost/test?poolSize=4';
mongoose.createConnection(uri);
Option Changes in v5.x
You may see the following deprecation warning if upgrading from 4.x to 5.x
and you didn't use the useMongoClient
option in 4.x:
the server/replset/mongos options are deprecated, all their options are supported at the top level of the options object
In older version of the MongoDB driver you had to specify distinct options for server connections, replica set connections, and mongos connections:
mongoose.connect(myUri, {
server: {
socketOptions: {
socketTimeoutMS: 0,
keepAlive: true
},
reconnectTries: 30
},
replset: {
socketOptions: {
socketTimeoutMS: 0,
keepAlive: true
},
reconnectTries: 30
},
mongos: {
socketOptions: {
socketTimeoutMS: 0,
keepAlive: true
},
reconnectTries: 30
}
});
In mongoose v5.x you can instead declare these options at the top level, without all that extra nesting. Here's the list of all supported options.
// Equivalent to the above code
mongoose.connect(myUri, {
socketTimeoutMS: 0,
keepAlive: true,
reconnectTries: 30
});
Next Up
Now that we've covered connections, let's take a look at models.