Fork me on GitHub

FAQ

Q. Why don't my changes to arrays get saved when I update an element directly?

doc.array[3] = 'changed';
doc.save();

A. Mongoose doesn't create getters/setters for array indexes; without them mongoose never gets notified of the change and so doesn't know to persist the new value. The work-around is to use MongooseArray#set available in Mongoose >= 3.2.0.

// 3.2.0
doc.array.set(3, 'changed');
doc.save();

// if running a version less than 3.2.0, you must mark the array modified before saving.
doc.array[3] = 'changed';
doc.markModified('array');
doc.save();

Q. I declared a schema property as unique but I can still save duplicates. What gives?

A. Mongoose doesn't handle unique on it's own, { name: { type: String, unique: true } } just a shorthand for creating a MongoDB unique index on name. For example, if MongoDB doesn't already have a unique index on name, the below code will not error despite the fact that unique is true.

var schema = new mongoose.Schema({
  name: { type: String, unique: true }
});
var Model = db.model('Test', schema);

Model.create([{ name: 'Val' }, { name: 'Val' }], function(err) {
  console.log(err); // No error, unless index was already built
});

However, if you wait for the index to build using the Model.on('index') event, attempts to save duplicates will correctly error.

var schema = new mongoose.Schema({
  name: { type: String, unique: true }
});
var Model = db.model('Test', schema);

Model.on('index', function(err) { // <-- Wait for model's indexes to finish
  assert.ifError(err);
  Model.create([{ name: 'Val' }, { name: 'Val' }], function(err) {
    console.log(err);
  });
});

MongoDB persists indexes, so you only need to rebuild indexes if you're starting with a fresh database or you ran db.dropDatabase(). In a production environment, you should [create your indexes using the MongoDB shell])(https://docs.mongodb.com/manual/reference/method/db.collection.createIndex/) rather than relying on mongoose to do it for you. The unique option for schemas is convenient for development and documentation, but mongoose is not an index management solution.


Q. When I have a nested property in a schema, mongoose adds empty objects by default. Why?

var schema = new mongoose.Schema({
  nested: {
    prop: String
  }
});
var Model = db.model('Test', schema);

// The below prints `{ _id: /* ... */, nested: {} }`, mongoose assigns
// `nested` to an empty object `{}` by default.
console.log(new Model());

A. This is a performance optimization. These empty objects are not saved to the database, nor are they in the result toObject(), nor do they show up in JSON.stringify() output unless you turn off the minimize option.

The reason for this behavior is that Mongoose's change detection and getters/setters are based on Object.defineProperty(). In order to support change detection on nested properties without incurring the overhead of running Object.defineProperty() every time a document is created, mongoose defines properties on the Model prototype when the model is compiled. Because mongoose needs to define getters and setters for nested.prop, nested must always be defined as an object on a mongoose document, even if nested is undefined on the underlying POJO.


Q. Why don't in-place modifications to date objects (e.g. date.setMonth(1);) get saved?

doc.createdAt.setDate(2011, 5, 1);
doc.save(); // createdAt changes won't get saved!

A. Mongoose currently doesn't watch for in-place updates to date objects. If you have need for this feature, feel free to discuss on this GitHub issue. There are several workarounds:

doc.createdAt.setDate(2011, 5, 1);
doc.markModified('createdAt');
doc.save(); // Works
doc.createdAt = new Date(2011, 5, 1).setHours(4);
doc.save(); // Works

Q. I'm populating a nested property under an array like the below code:

new Schema({ arr: [{ child: { ref: 'OtherModel', type: Schema.Types.ObjectId } }] });

.populate({ path: 'arr.child', options: { sort: 'name' } }) won't sort by arr.child.name?

A. See this GitHub issue. It's a known issue but one that's exceptionally difficult to fix.


Q. All function calls on my models hang, what am I doing wrong?

A. By default, mongoose will buffer your function calls until it can connect to MongoDB. Read the buffering section of the connection docs for more information.


Q. How can I enable debugging?

A. Set the debug option to true:

mongoose.set('debug', true)

All executed collection methods will log output of their arguments to your console.


Q. My save() callback never executes. What am I doing wrong?

A. All collection actions (insert, remove, queries, etc.) are queued until the connection opens. It is likely that an error occurred while attempting to connect. Try adding an error handler to your connection.

// if connecting on the default mongoose connection
mongoose.connect(..);
mongoose.connection.on('error', handleError);

// if connecting on a separate connection
var conn = mongoose.createConnection(..);
conn.on('error', handleError);

Q. Should I create/destroy a new connection for each database operation?

A. No. Open your connection when your application starts up and leave it open until the application shuts down.


Q. Why do I get "OverwriteModelError: Cannot overwrite .. model once compiled" when I use nodemon / a testing framework?

A. mongoose.model('ModelName', schema) requires 'ModelName' to be unique, so you can access the model by using mongoose.model('ModelName'). If you put mongoose.model('ModelName', schema); in a mocha beforeEach() hook, this code will attempt to create a new model named 'ModelName' before every test, and so you will get an error. Make sure you only create a new model with a given name once. If you need to create multiple models with the same name, create a new connection and bind the model to the connection.

var mongoose = require('mongoose');
var connection = mongoose.createConnection(..);

// use mongoose.Schema
var kittySchema = mongoose.Schema({ name: String });

// use connection.model
var Kitten = connection.model('Kitten', kittySchema);

Something to add?

If you'd like to contribute to this page, please visit it on github and use the Edit button to send a pull request.