Mongoose setters have always had the limitation that they only work for save() , not for queries. For example, let's say you have a schema that enforces your emails are always lowercase:

const schema = Schema({ email: { type: String , lowercase: true } }); const PersonModel = mongoose.model( 'Person' , schema);

Creating and saving an instance of PersonModel will ensure that email is converted to lowercase before saving.

const val = new PersonModel({ email: 'Val@test.com' }); console .log(val.email); val.save( function ( error, val ) { console .log(val.email); });

In general, any time you create a mongoose document, you'll get a lowercased email. Because insertMany() and create() use mongoose documents, they'll lowercase emails as well. However, mongoose 4.x will not lowercase email with find() , findOneAndUpdate() , or any other query options.

PersonModel.find({ email: 'Val@test.com' }); PersonModel.findOneAndUpdate({}, { email: 'Val@test.com' }, { upsert: true });

The runSettersOnQuery Option

Mongoose 4.10 has an opt-in option on the schema level that will run setters for queries.

const schema = Schema({ email: { type: String , lowercase: true } }, { runSettersOnQuery: true }); PersonModel.find({ email: 'Val@test.com' }); PersonModel.findOneAndUpdate({}, { email: 'Val@test.com' }, { upsert: true });

Mongoose will also run any custom setters you may have. For example, let's say you have a setter that ensures that the num property is an integer:

const schema = Schema({ num: { type: String , set: v => Math .floor(v) } }, { runSettersOnQuery: true }); NumModel.find({ num: 3.14 }); NumModel.findOneAndUpdate({}, { num: 2.718 }, { upsert: true });

Setter Context

Like running validation on update() , the reason why mongoose does not run setters on queries by default because of function context. If you create a new document, setters can access the document using this :

; const schema = Schema({ num: { type: String , set: function ( v ) { console .log( this ); return v; } } }, { runSettersOnQuery: true }); const NumModel = mongoose.model( 'Num' , schema); new NumModel({ num: 3 }); NumModel.find({ num: 3 });

For built-in mongoose setters ( lowercase , uppercase , trim ) this is a non-issue. However, community plugins often rely on setter context, so we're not turning this on by default in 4.x. We're planning on turning it on by default in 5.0, so if you have concerns, please voice them on this GitHub issue.

Moving On

Mongoose 4.10 has 8 powerful new features and several small bug fixes, including aliasing and unique in arrays. Make sure you upgrade to take advantage of these powerful new features!