Skip to content

Commit

Permalink
Merge branch '4.13' into 1939
Browse files Browse the repository at this point in the history
  • Loading branch information
vkarpov15 committed Oct 30, 2017
2 parents a7518bd + b9c2d3a commit 9b0525b
Show file tree
Hide file tree
Showing 51 changed files with 1,543 additions and 315 deletions.
43 changes: 43 additions & 0 deletions History.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,46 @@
4.12.5 / 2017-10-29
===================
* fix(query): correctly handle `$in` and required for $pull and update validators #5744
* feat(aggegate): add $addFields pipeline operator #5740 [AyushG3112](https://github.com/AyushG3112)
* fix(document): catch sync errors in document pre hooks and report as error #5738
* fix(populate): handle slice projections correctly when automatically selecting populated fields #5737
* fix(discriminator): fix hooks for embedded discriminators #5706 [wlingke](https://github.com/wlingke)
* fix(model): throw sane error when customer calls `mongoose.Model()` over `mongoose.model()` #2005

4.12.4 / 2017-10-21
===================
* test(plugins): add coverage for idGetter with id as a schema property #5713 [wlingke](https://github.com/wlingke)
* fix(model): avoid copying recursive $$context object when creating discriminator after querying #5721
* fix(connection): ensure connection promise helpers are removed before emitting 'connected' #5714
* docs(schema): add notes about runSettersOnQuery to schema setters #5705
* fix(collection): ensure queued operations run on the next tick #5562

4.12.3 / 2017-10-16
===================
* fix(connection): emit 'reconnect' event as well as 'reconnected' for consistency with driver #5719
* fix: correctly bubble up left/joined events for replica set #5718
* fix(connection): allow passing in `autoIndex` as top-level option rather than requiring `config.autoIndex` #5711
* docs(connection): improve docs regarding reconnectTries, autoReconnect, and bufferMaxEntries #5711
* fix(query): handle null with addToSet/push/pull/pullAll update validators #5710
* fix(model): handle setDefaultsOnInsert option for bulkWrite updateOne and updateMany #5708
* fix(query): avoid infinite recursion edge case when cloning a buffer #5702

4.12.2 / 2017-10-14
===================
* docs(faq): add FAQ about using arrow functions for getters/setters, virtuals, and methods #5700
* docs(schema): document the childSchemas property and add to public API #5695
* fix(query): don't project in populated field if parent field is already projected in #5669
* fix: bump mongodb -> 2.2.33 for issue with autoReconnect #4513

4.12.1 / 2017-10-08
===================
* fix(document): create new doc when setting single nested, no more set() on copy of priorVal #5693
* fix(model): recursively call applyMethods on child schemas for global plugins #5690
* docs: fix bad promise lib example on home page #5686
* fix(query): handle false when checking for inclusive/exclusive projection #5685
* fix(discriminator): allow reusing child schema #5684
* fix: make addToSet() on empty array with subdoc trigger manual population #5504

4.12.0 / 2017-10-02
===================
* docs(validation): add docs coverage for ValidatorError.reason #5681
Expand Down
78 changes: 37 additions & 41 deletions docs/connections.jade
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ block content
on the default port (27017). If the local connection fails then try using
127.0.0.1 instead of localhost. Sometimes issues may arise when the local
hostname has been changed.

You can also specify several more parameters in the `uri`:

:js
Expand All @@ -26,82 +26,78 @@ block content
:markdown
Mongoose lets you start using your models immediately, without waiting for
mongoose to establish a connection to MongoDB.

:js
mongoose.connect('mongodb://localhost/myapp');
var MyModel = mongoose.model('Test', new Schema({ name: String }));
// Works
MyModel.findOne(function(error, result) { /* ... */ });

:markdown
That's because mongoose buffers model function calls internally. This
buffering is convenient, but also a common source of confusion. Mongoose
will *not* throw any errors by default if you use a model without
connecting.

:js
var MyModel = mongoose.model('Test', new Schema({ name: String }));
// Will just hang until mongoose successfully connects
MyModel.findOne(function(error, result) { /* ... */ });

setTimeout(function() {
mongoose.connect('mongodb://localhost/myapp');
}, 60000);

:markdown
To disable buffering, turn off the [`bufferCommands` option on your schema](http://mongoosejs.com/docs/guide.html#bufferCommands).
If you have `bufferCommands` on and your connection is hanging, try turning
`bufferCommands` off to see if you haven't opened a connection properly.

h3#options Options
:markdown
The `connect` method also accepts an `options` object which will be passed on to the underlying driver. All options included here take precedence over options passed in the connection string.
The `connect` method also accepts an `options` object which will be passed on to the underlying MongoDB driver.

:js
mongoose.connect(uri, options);

:markdown
The following option keys are available:

db - passed to the [underlying driver's db instance](http://mongodb.github.io/node-mongodb-native/2.1/api/Db.html)
server - passed to the [underlying driver's server instance(s)](http://mongodb.github.io/node-mongodb-native/2.1/api/Server.html)
replset - passed to the [underlying driver's ReplSet instance](http://mongodb.github.io/node-mongodb-native/2.1/api/ReplSet.html)
user - username for authentication (if not specified in uri)
pass - password for authentication (if not specified in uri)
auth - options for authentication
mongos - passed to the [underlying driver's mongos options](http://mongodb.github.io/node-mongodb-native/2.1/api/Mongos.html)
promiseLibrary - sets the [underlying driver's promise library](http://mongodb.github.io/node-mongodb-native/2.1/api/MongoClient.html)
A full list of options can be found on the [MongoDB Node.js driver docs for `connect()`](http://mongodb.github.io/node-mongodb-native/2.2/api/MongoClient.html#connect).
Mongoose passes options to the driver without modification, modulo three exceptions that are explained below.

* `useMongoClient` - This is a mongoose-specific option (not passed to the MongoDB driver) that opts in to mongoose 4.11's new connection logic. If you are writing a new application, you **should** set this to `true`.
* `user`/`pass` - The username and password for authentication. These options are mongoose-specific, they are equivalent to the MongoDB driver's `auth.user` and `auth.password` options.
* `autoIndex` - By default, mongoose will automatically build indexes defined in your schema when it connects. This is great for development, but not ideal for large production deployments, because index builds can cause performance degradation. If you set `autoIndex` to false, mongoose will not automatically build indexes for **any** model associated with this connection.

Below are some of the options that are important for tuning mongoose.

* `autoReconnect` - The underlying MongoDB driver will automatically try to reconnect when it loses connection to MongoDB. Unless you are an extremely advanced user that wants to manage their own connection pool, do **not** set this option to `false`.
* `reconnectTries` - If you're connected to a single server or mongos proxy (as opposed to a replica set), the MongoDB driver will try to reconnect every `reconnectInterval` milliseconds for `reconnectTries` times, and give up afterward. When the driver gives up, the mongoose connection emits a `reconnectFailed` event. This option does nothing for replica set connections.
* `reconnectInterval` - See `reconnectTries`
* `promiseLibrary` - sets the [underlying driver's promise library](http://mongodb.github.io/node-mongodb-native/2.1/api/MongoClient.html)
* `poolSize` - The maximum number of sockets the MongoDB driver will keep open for this connection. By default, `poolSize` is 5. Keep in mind that, as of MongoDB 3.4, MongoDB only allows one operation per socket at a time, so you may want to increase this if you find you have a few slow queries that are blocking faster queries from proceeding.
* `bufferMaxEntries` - The MongoDB driver also has its own buffering mechanism that kicks in when the driver is disconnected. Set this option to 0 and set `bufferCommands` to `false` on your schemas if you want your database operations to fail immediately when the driver is not connected, as opposed to waiting for reconnection.

Example:
:js
var options = {
db: { native_parser: true },
server: { poolSize: 5 },
replset: { rs_name: 'myReplicaSetName' },
user: 'myUserName',
pass: 'myPassword'
}
useMongoClient: true,
autoIndex: false, // Don't build indexes
reconnectTries: Number.MAX_VALUE, // Never stop trying to reconnect
reconnectInterval: 500, // Reconnect every 500ms
poolSize: 10, // Maintain up to 10 socket connections
// If not connected, return errors immediately rather than waiting for reconnect
bufferMaxEntries: 0
};
mongoose.connect(uri, options);
:markdown
**Note:**
The server option `auto_reconnect` is defaulted to true which _can_ be overridden.
The db option `forceServerObjectId` is set to false which _cannot_ be overridden.

See the [driver](https://github.com/mongodb/node-mongodb-native) for more information about available options.
:markdown
**Note:**
If `auto_reconnect` is on, mongoose will give up trying to reconnect after a certain number of failures. Set the [`server.reconnectTries` and `server.reconnectInterval` options](http://mongodb.github.io/node-mongodb-native/2.1/api/Server.html) to increase the number of times mongoose will try to reconnect.
:js
// Good way to make sure mongoose never stops trying to reconnect
mongoose.connect(uri, { server: { reconnectTries: Number.MAX_VALUE } });

h3#callback Callback
:markdown
The `connect()` function also accepts a callback parameter and returns a [promise](http://mongoosejs.com/docs/promises.html).
:js
mongoose.connect(uri, options, function(error) {
// Check error in initial connection. There is no 2nd param to the callback.
});

// Or using promises
mongoose.connect(uri, options).then(
() => { /** ready to use. The `mongoose.connect()` promise resolves to undefined. */ },
Expand All @@ -111,7 +107,7 @@ block content
h4#connection-string-options Connection String Options
:markdown
Mongoose supports the following options in the connection string.

* [ssl](http://mongodb.github.io/node-mongodb-native/2.1/api/Server.html)
* [poolSize](http://mongodb.github.io/node-mongodb-native/2.1/api/Server.html)
* [autoReconnect](http://mongodb.github.io/node-mongodb-native/2.1/api/Server.html)
Expand Down Expand Up @@ -155,7 +151,7 @@ block content

:markdown
To connect to a single node replica set, specify the `replicaSet` option.

:js
mongoose.connect('mongodb://host1:port1/?replicaSet=rsName');

Expand All @@ -179,7 +175,7 @@ block content

h3#connection_pools Connection pools
:markdown
Each `connection`, whether created with `mongoose.connect` or `mongoose.createConnection` are all backed by an internal configurable connection pool defaulting to a size of 5. Adjust the pool size using your connection options:
Each `connection`, whether created with `mongoose.connect` or `mongoose.createConnection` are all backed by an internal configurable connection pool defaulting to a maximum size of 5. Adjust the pool size using your connection options:

:js
// single server
Expand All @@ -192,7 +188,7 @@ block content
// passing the option in the URI works with single or replica sets
var uri = 'mongodb://localhost/test?poolSize=4';
mongoose.createConnection(uri);

h3#use-mongo-client The `useMongoClient` Option
:markdown
Mongoose's default connection logic is deprecated as of 4.11.0. Please opt
Expand Down Expand Up @@ -261,7 +257,7 @@ block content
keepAlive: true,
reconnectTries: 30
});

:markdown
This deprecation is because the [MongoDB driver](https://www.npmjs.com/package/mongodb)
has deprecated an API that is critical to mongoose's connection logic to
Expand Down
60 changes: 44 additions & 16 deletions docs/faq.jade
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ block content
doc.array[3] = 'changed';
doc.markModified('array');
doc.save();

hr#unique-doesnt-work
:markdown
**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`](https://docs.mongodb.com/manual/core/index-unique/).
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.
Expand All @@ -61,7 +61,7 @@ block content
console.log(err);
});
});

// Promise based alternative. `init()` returns a promise that resolves
// when the indexes have finished building successfully. The `init()`
// function is idempotent, so don't worry about triggering an index rebuild.
Expand All @@ -77,7 +77,7 @@ block content
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.

hr#nested-properties
:markdown
**Q**. When I have a nested property in a schema, mongoose adds empty objects by default. Why?
Expand All @@ -88,15 +88,15 @@ block content
}
});
var Model = db.model('Test', schema);

// The below prints `{ _id: /* ... */, nested: {} }`, mongoose assigns
// `nested` to an empty object `{}` by default.
console.log(new Model());
:markdown
**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](http://mongoosejs.com/docs/guide.html#minimize).

The reason for this behavior is that Mongoose's change detection
and getters/setters are based on [`Object.defineProperty()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty).
In order to support change detection on nested properties without incurring
Expand All @@ -105,7 +105,35 @@ block content
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](http://mongoosejs.com/docs/guide.html#minimize).


hr#arrow-functions
:markdown
**Q**. I'm using an arrow function for a [virtual](http://mongoosejs.com/docs/guide.html#virtuals), getter/setter, or [method](http://mongoosejs.com/docs/guide.html#methods) and the value of `this` is wrong.

**A**. Arrow functions [handle the `this` keyword much differently than conventional functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#No_binding_of_this).
Mongoose getters/setters depend on `this` to give you access to the document that you're writing to, but this functionality does not work with arrow functions. Do **not** use arrow functions for mongoose getters/setters unless do not intend to access the document in the getter/setter.
:js
// Do **NOT** use arrow functions as shown below unless you're certain
// that's what you want. If you're reading this FAQ, odds are you should
// just be using a conventional function.
var schema = new mongoose.Schema({
propWithGetter: {
type: String,
get: v => {
// Will **not** be the doc, do **not** use arrow functions for getters/setters
console.log(this);
return v;
}
}
});

// `this` will **not** be the doc, do **not** use arrow functions for methods
schema.method.arrowMethod = () => this;
schema.virtual('virtualWithArrow').get(() => {
// `this` will **not** be the doc, do **not** use arrow functions for virtuals
console.log(this);
});

hr#date_changes
:markdown
**Q**. Why don't in-place modifications to date objects
Expand All @@ -125,33 +153,33 @@ block content
:js
doc.createdAt = new Date(2011, 5, 1).setHours(4);
doc.save(); // Works

hr#populate_sort_order
:markdown
**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`?

:markdown
**A**. See [this GitHub issue](https://github.com/Automattic/mongoose/issues/2202). It's a known issue but one that's exceptionally difficult to fix.

hr#model_functions_hanging
:markdown
**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](http://mongoosejs.com/docs/connections.html#buffering)
for more information.

hr#enable_debugging
:markdown
**Q**. How can I enable debugging?
Expand Down Expand Up @@ -183,7 +211,7 @@ block content
:markdown
**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
Expand All @@ -198,7 +226,7 @@ block content

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

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

Expand Down
16 changes: 11 additions & 5 deletions docs/middleware.jade
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ block content
Middleware (also called pre and post *hooks*) are functions which are passed
control during execution of asynchronous functions. Middleware is specified
on the schema level and is useful for writing [plugins](./plugins.html).
Mongoose 4.x has 3 types
of middleware: document middleware, model middleware, and query middleware.
Mongoose 4.x has 4 types
of middleware: document middleware, model middleware, aggregate middleware, and query middleware.
Document middleware is supported for the following document functions.
In document middleware functions, `this` refers to the document.
In document middleware functions, `this` refers to the document.

* [init](./api.html#document_Document-init)
* [validate](./api.html#document_Document-validate)
Expand All @@ -25,10 +25,16 @@ block content
* [findOneAndRemove](./api.html#query_Query-findOneAndRemove)
* [findOneAndUpdate](./api.html#query_Query-findOneAndUpdate)
* [update](./api.html#query_Query-update)


Aggregate middleware is for `MyModel.aggregate()`. Aggregate middleware
executes when you call `exec()` on an aggregate object.
In aggregate middleware, `this` refers to the [aggregation object](http://mongoosejs.com/docs/api.html#model_Model.aggregate).

* [aggregate](http://mongoosejs.com/docs/api.html#model_Model.aggregate)

Model middleware is supported for the following model functions.
In model middleware functions, `this` refers to the model.

* [insertMany](./api.html#model_Model.insertMany)

All middleware types support pre and post hooks.
Expand Down
Loading

0 comments on commit 9b0525b

Please sign in to comment.