If I add a property to a Mongoose schema and give it a default value, will existing documents receive these defaults when they are loaded?
2 Answers
Yes, but not if the query is lean
.
For queries that return a full Mongoose document object – Thing.find({...})
– the default value will be returned whenever the property is missing, regardless of when the schema was changed. If the document is subsequently saved, the default value will be materialised in the database.
If the query is lean
– Thing.find({...}).lean()
– the query returns only what's in the database and this doesn't include any newly added defaults (unless the document has been loaded and saved, as above).

- 22,122
- 12
- 111
- 127
-
3How can we use lean with mongo defaults on existing documents? Eventually, I have to use (as many others do) `.lean()`. – Yagiz Aug 02 '16 at 21:53
-
2Collection.aggregate({}) also doesn't enfore the default parameters. – null1941 Jun 12 '19 at 08:44
You can customize default
to ignore the case where documents already exist.
Instead of doing default: Date.now
, where existing documents when fetched will show the current date even if it's not set in the db, you could do this:
default: function() {
if (this.isNew) {
return Date.now();
}
return void 0;
}
Now, existing documents that do not have the field set in the db will not have it set when fetched.

- 7,937
- 5
- 33
- 26
-
-
in addition to this answer, make sure you're not using arrow functions, and if you have `select: false` keep the defaults normally without having it be a function, because `isNew()` will not be in the scope of `$this` when this field is executed in case you have the `select` prop. – Normal Sep 04 '22 at 09:37