Fork me on GitHub

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.

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 three exceptions that are explained below.

Below are some of the options that are important for tuning mongoose.

Example:

var 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 options in your connection string as parameters in the query string portion of the URI.

mongoose.connect('mongodb://localhost:27017/test?connectTimeoutMS=1000', { useMongoClient: true });
// The above is equivalent to:
mongoose.connect('mongodb://localhost:27017/test', {
  useMongoClient: true,
  connectTimeoutMS: 1000
});

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:

options.server.socketOptions = options.replset.socketOptions = { keepAlive: 120 };
mongoose.connect(uri, options);

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

High availability over multiple mongos instances is also supported. Pass a connection string for your mongos instances. If you are not using the useMongoClient option, you must also set the mongos option:

mongoose.connect('mongodb://mongosA:27501,mongosB:27501', { mongos: true }, cb);

With useMongoClient, you do not need to set the mongos option. You also do not need to use mongos or useMongoClient in mongoose 5.x.

mongoose.connect('mongodb://mongosA:27501,mongosB:27501', { useMongoClient: true }, 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.

var 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.

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:

// single server
var uri = 'mongodb://localhost/test';
mongoose.createConnection(uri, { server: { poolSize: 4 }});

// for a replica set
mongoose.createConnection(uri, { replset: { poolSize: 4 }});

// passing the option in the URI works with single or replica sets
var uri = 'mongodb://localhost/test?poolSize=4';
mongoose.createConnection(uri);

The `useMongoClient` Option

Mongoose's default connection logic is deprecated as of 4.11.0. Please opt in to the new connection logic using the useMongoClient option, but make sure you test your connections first if you're upgrading an existing codebase!

// Using `mongoose.connect`...
var promise = mongoose.connect('mongodb://localhost/myapp', {
  useMongoClient: true,
  /* other options */
});
// Or `createConnection`
var promise = mongoose.createConnection('mongodb://localhost/myapp', {
  useMongoClient: true,
  /* other options */
});
promise.then(function(db) {
  /* Use `db`, for instance `db.model()`
});
// Or, if you already have a connection
connection.openUri('mongodb://localhost/myapp', { /* options */ });

The parameters to openUri() are passed transparently to the underlying MongoDB driver's MongoClient.connect() function. Please see the driver documentation for this function for options. The same is true for connect() and createConnection() if useMongoClient is true.

You may see the following deprecation warning with useMongoClient:

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
  }
});

With useMongoClient 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
});

This deprecation is because the MongoDB driver has deprecated an API that is critical to mongoose's connection logic to support MongoDB 3.6, see this github issue and this blog post for more details.

Next Up

Now that we've covered connections, let's take a look at how we can break pieces of our functionality out into reusable and shareable plugins.