Migrating from 2.x to 3.x

Migrating from Mongoose 2.x to 3.x brings with it several changes to be aware of:

Query clean-up

Many methods of the Query API were nothing but aliases and have been removed in an effort to keep Mongoose clean and focused on there being as close to one way of doing things as possible. If you really love all that extra noise, you can bring most of it back with this module.

Here are the removed methods and their still existing aliases:

RemovedAlternative
query.runquery.exec
query.$orquery.or
query.$norquery.nor
query.$gtquery.gt
query.$gtequery.gte
query.$ltquery.lt
query.$ltequery.lte
query.$nequery.ne
query.$inquery.in
query.$ninquery.nin
query.$allquery.all
query.$regexquery.regex
query.$sizequery.size
query.$maxDistancequery.maxDistance
query.$modquery.mod
query.$nearquery.near
query.$existsquery.exists
query.$elemMatchquery.elemMatch
query.$withinquery.within
query.$boxquery.box
query.$centerquery.center
query.$centerSpherequery.centerSphere
query.$slicequery.slice
query.notEqualToquery.ne
query.whereinquery.within
query.ascquery.sort
query.descquery.sort
query.fieldsquery.select *

query#asc

The asc method of Query has been removed in favor of sort. The sort method accepts slightly different arguments so read the docs to make sure your application is all set.

query#desc

The desc method of Query has been removed in favor of sort. The sort method accepts slightly different arguments so read the docs to make sure your application is all set.

query#sort

The sort method of Queries now accepts slightly different arguments. Read the docs to make sure your application is all set.

query#fields

The fields method of Query has been removed, it being mostly an alias for the select method anyway. The select method has slightly different arguments so read the docs to make sure your application is all set.

Because of the change to the fields method, the field selection argument for query.populate and model methods like findById, find, etc, is slightly different as well (no longer accepts arrays for example), so read the docs to make sure your application is all set.

Connecting to ReplicaSets

To connect to a ReplicaSet you no longer use the separate connectSet or createSetConnection methods. Both mongoose.connect and mongoose.createConnection are now smart enough to just do the right thing with your connection string. If you really want to bring connectSet and createSetConnection back use this module.

Schemas

Schemas are now strict by default. This means that if you depended on saving fields not defined in the schema, you may lose data unless you set this back to false.

  • Arrays of object literal now creates document arrays instead of arrays of Mixed.
  • Indexes are now created in background by default.
  • Index errors are now emitted on their model instead of the connection. See issue #984.

Arrays

  • pop is now fixed causing a $set of the entire array.
  • $pop is now fixed and behaves just as MongoDB $pop does, removing at most the last element of the array.
  • shift is now fixed causing a $set of the entire array.
  • $shift is now fixed and behaves just as a MongoDB $pop -1 does, removing at most the first element of array.
  • $unshift was removed, use unshift instead.
  • $addToSet was removed, use addToSet instead.
  • $pushAll was removed, use push instead.
  • $pull was removed, use pull instead.
  • $pullAll was removed, use pull instead.
  • doAtomics was changed to the hasAtomics private method

Number type

The custom subclassed Number type Mongoose used to use for all numbers is now gone. It caused too many problems when doing comparisons and had other bad side-effects.

With it out of the picture, the following helper methods of MongooseNumbers are now also gone:

  • $inc
  • $increment
  • $decrement

If you really want this behavior back, include the mongoose-number module in your project.

A good alternative is to start using the new findAndModify helpers. Say we have an inventory of 10 products and a customer purchases 7 of them. In Mongoose v2 you could have depended on MongooseNumber:

  1. var inventorySchema = new Schema({ productCount: Number });
  2. ...
  3. Inventory.findById(id, function (err, inventory) {
  4. if (err) return handleError(err);
  5. inventory.productCount.$decrement(7);
  6. inventory.save(function (err) {
  7. // sends Inventory.update({ _id: id }, { $inc: { balance: -7 }}, callback);
  8. if (err) return handleError(err);
  9. res.send(inventory.productCount); // 3
  10. });
  11. });

With MongooseNumber out of the picture, we’ll instead use the Account.findByIdAndUpdate helper:

  1. Inventory.findByIdAndUpdate(id, { $inc: { productCount: -7 }}, function (err, inventory) {
  2. if (err) return handleError(err);
  3. res.send(inventory.productCount); // 3
  4. });

The findByIdAndUpdate helper not only finds the document but updates it as well before responding with the altered document. The findAndModify helpers are a great addition for many use cases.

Documents

getter casting

Getters no longer apply casting. Casting happens at set time. Useful in situations where you desire formatted responses like currency. See issue #820 and pull #924.

setter order

Values being set no longer cast until after all setters have been applied. Previously the value returned from each setter was cast before passing it on to the next setter. This change allows more flexible processing of values in setters. See issue #665 and pull #924.

Subdocuments

  • subdoc.parent was changed from a property to a method. See issue #928.
  • subdoc.parentArray was changed from a property to a method. See issue #928.

String match validator

The String SchemaType match validator no longer checks against null, undefined, or ‘’. If you need to validate against these values, enable the required validator as well. See issue #934 and pull request #935.

Versioning

Documents are now transparently versioned. Read the in depth details here.

More Info

Related blog posts: