Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongoose indexing in production code

People also ask

What is Mongoose indexing?

Indexes are defined through ensureIndex every time a model is compiled for a certain connection / database. This means that indexes will only be ensured once during the lifetime of your app.

Is Mongoose an ORM or ODM?

Mongoose is an ODM that provides a straightforward and schema-based solution to model your application data on top of MongoDB's native drivers.

What is autoIndex in MongoDB?

The chapter 5 of M001 discusses about indexes as a way to make queries efficient and much faster. Also note, that autoIndex does not mean that you create an index for every field. Instead, it means: Mongoose automatically calls createIndex for each defined index in your schema.

What does it mean that Mongoose is an ODM?

Mongoose is an Object Data Modeling (ODM) library for MongoDB and Node. js. It manages relationships between data, provides schema validation, and is used to translate between objects in code and the representation of those objects in MongoDB.


I've never understood why the Mongoose documentation so broadly recommends disabling autoIndex in production. Once the index has been added, subsequent ensureIndex calls will simply see that the index already exists and then return. So it only has an effect on performance when you're first creating the index, and at that time the collections are often empty so creating an index would be quick anyway.

My suggestion is to leave autoIndex enabled unless you have a specific situation where it's giving you trouble; like if you want to add a new index to an existing collection that has millions of docs and you want more control over when it's created.


Although I agree with the accepted answer, its worth noting that according to the MongoDB manual, this isn't the recommended way of adding indexes on a production server:

If your application includes ensureIndex() operations, and an index doesn’t exist for other operational concerns, building the index can have a severe impact on the performance of the database.

To avoid performance issues, make sure that your application checks for the indexes at start up using the getIndexes() method or the equivalent method for your driver and terminates if the proper indexes do not exist. Always build indexes in production instances using separate application code, during designated maintenance windows.

Of course, it really depends on how your application is structured and deployed. If you are deploying to Heroku, for example, and you aren't using Heroku's preboot feature, then it is likely your application is not serving requests at all during startup, and so it's probably safe to create an index at that time.

In addition to this, from the accepted answer:

So it only has an effect on performance when you're first creating the index, and at that time the collections are often empty so creating an index would be quick anyway.

If you've managed to get your data model and queries nailed on first time around, this is fine, and often the case. However, if you are adding new functionality to your app, with a new DB query on a property without an index, you'll often find yourself adding an index to a collection containing many existing documents.

This is the time when you need to be careful about adding indexes, and carefully consider the performance implications of doing so. For example, you could create the index in the background:

db.ensureIndex({ name: 1 }, { background: true });

use this block code to handle production mode:

const autoIndex = process.env.NODE_ENV !== 'production';
mongoose.connect('mongodb://localhost/collection', { autoIndex });