Mongoose 4.0 brings some exciting new functionality: schema validation in the browser, query middleware, validation on update, and promises for async operations. In addition to these improvements, there are a few backwards breaking changes to be aware of when you choose to upgrade. The 3.8 branch will continue to be maintained until September 2015.
First, a note on versioning. As of 4.0, Mongoose will return to using semantic versioning rather than the even/odd versioning system that NodeJS and MongoDB use. The even/odd versioning caused a lot of confusion and made releases much larger than they had to be. Releases will be smaller and more focused going forward. Each Mongoose release after 4.0 will be considered production-ready, and there will be no more backwards-breaking changes until 5.0.
Backwards-Breaking Changes
- #1323: CastError and ValidationError’s ‘type’ field has been renamed ‘kind’ to avoid interfering with V8’s usage of error.type.
- #1349:
setProfiling()
was removed. - #1351: Document no longer inherits from
EventEmitter
. Documents still fulfill the NodeJS EventEmitter API through function wrappers, butDocument instanceof EventEmitter
is no longer true. This is to prevent users from accidentally clobbering EventEmitter internals by creating schema paths named “domain”, “_events”, etc. - #1530: If you set a field with the ‘ref’ property to a document whose model name is equal to the ‘ref’, mongoose will treat the field as if it were
.populate()
-ed. - #1594: If you set a field to
undefined
after you already set it, validators will no longer be run (except, of course, therequired
validator, if specified). - #1746:
Model.create()
will return a spread of documents if you pass it a spread, and an array if you pass it an array. In 3.8.xModel.create()
always returned a spread. - #1892: Setters are now called even when the value is set to
undefined
- #2243: When you specify multiple validators on a field, they will now be run in the order specified, as opposed to reverse order.
- #2262: The
findOneAndUpdate()
,findByIdAndUpdate()
, etc.new
option is now false by default. The MongoDB server assumes false by default, this change is so mongoose is more consistent with the server’s API. - #2306: If
options.cursor
is specified,aggregate.exec()
will return a cursor and ignore any callback. - #2380: “save” and “validate” may no longer be schema path names.
- #2552: Upgraded mongodb driver to 2.0.x. Mongoose is a wrapper layer on top of the MongoDB node driver. The mongodb driver recently released version 2.0, which includes numerous performance and usability improvements. The new driver, however, introduces a few changes that affect the way you use Mongoose:
- If you are connecting to a replica set, you must specify the
replicaSet
option in the connection string. update
returns a result object from the MongoDB server, rather than just the number affected. The second parameter to the callback will now look like{ ok: 1, n: 3 }
rather than simply the number affected.
- If you are connecting to a replica set, you must specify the
- #2589:
validate()
now collects all subdocument errors rather than stopping after the first subdocument errors out. - #2592: setting a nested path to a non-object value now triggers a CastError
- #2611:
validate()
now checks for cast errors. - #2628: 3.x reversed the order for
distinct()
parameters inlib/query.js
. For instance, you calleddistinct()
on a model like so:Model.distinct(field, criteria, callback)
. But, if you were using a query instance, you had to reverse the field and criteria, for instance,Model.find().distinct(criteria, field, callback)
. 4.0 makes this order consistent, so you can useModel.find().distinct(field, criteria, callback)
. - #2698: Setters are now applied on paths with
ref
set - #2709:
increment
is now a reserved path - #2775: CastErrors are tracked on a per-path basis. If you set a path to a valid value, this will clear all CastErrors and any other calls to
invalidate()
. Array
andDocumentArray
are now functions that return an array, rather than constructors. For instance,new MongooseArray([]) instanceof MongooseArray
isfalse
in 4.0. To check whether an array is a MongooseArray, use theisMongooseArray
andisMongooseDocumentArray
properties. This is in order for Mongoose’s isomorphic component (see #2254) to support non-ES5 compatible browsers (such as IE8) without a shim.- #3763: limit() and skip() now require their input to be numbers. Mongoose 3.8 was already documented to require numbers here, but previously strings were accepted and cast to numbers. Passing numbers as strings will now throw a parse error.
New Features
- #661: Can now specify validators for array elements
- #860: You can optionally run validators and set defaults if a new document is created on
update()
andfindOneAndUpdate()
calls. In order to access these features, you must explicitly set therunValidators
andsetDefaultsOnInsert
options when you callupdate()
orfindOneAndUpdate()
. Note that thesetDefaultsOnInsert
option is not compatible with MongoDB <= 2.2. Further noteupdate()
andfindOneAndUpdate()
explicitly run validators with a null context (that is,this === null
in the validator function). - #1401: You can add fields to
text
indexes in the field declaration itself. - #1416: You can now use properties named
options
in your schemas - #1967:
findOneAndUpdate()
now supports thestrict
option - #2138: Query middleware. You can now specify hooks like
schema.pre('find')
andschema.post('findOne')
. - #2177: Async operations return promises that are compatible with the
yield
keyword in ES6. - #2441: hooks no longer hangs when you return an error that isn’t of type
Error
. - #2494: You can pass a write concern to
save()
. - #2531: You can now specify
min
andmax
validators fortype: Date
. - #2640: Ability to populate using different models
- #2675:
toObject()
now has aversionKey
option (true
by default) that you can use to remove the version key fromtoObject()
output - #2719: Populate() now can populate with discriminator child schema
- Mongoose is now partially isomorphic. You can
require('mongoose')
in your Browserify-built applications or include a browser-friendly JS file with ascript
tag. The browser-side code is limited to Mongoose schema validation. Mongoose’s browser component is tested using SauceLabs on the browsers specified inkarma.sauce.conf.js
. In particular, Mongoose supports IE >= 9, Safari >= 6, mobile browsers, Chrome, and Firefox. Mongoose 4.0 is not expected to work on IE8.