diff --git a/lib/model.js b/lib/model.js index c386077e880..bcb811ccac0 100644 --- a/lib/model.js +++ b/lib/model.js @@ -96,7 +96,7 @@ const saveToObjectOptions = Object.assign({}, internalToObjectOptions, { * const userFromDb = await UserModel.findOne({ name: 'Foo' }); * * @param {Object} doc values for initial set - * @param [fields] optional object containing the fields that were selected in the query which returned this document. You do **not** need to set this parameter to ensure Mongoose handles your [query projection](./api.html#query_Query-select). + * @param {Object} [fields] optional object containing the fields that were selected in the query which returned this document. You do **not** need to set this parameter to ensure Mongoose handles your [query projection](./api.html#query_Query-select). * @param {Boolean} [skipId=false] optional boolean. If true, mongoose doesn't add an `_id` field to the document. * @inherits Document https://mongoosejs.com/docs/api/document.html * @event `error`: If listening to this event, 'error' is emitted when a document was saved without passing a callback and an `error` occurred. If not listening, the event bubbles to the connection used to create this Model. @@ -210,6 +210,7 @@ Model.prototype.baseModelName; * await MyModel.findOne({ _id: 'Not a valid ObjectId' }).catch(noop); * * @api public + * @property events * @fires error whenever any query or model function errors * @memberOf Model * @static @@ -888,26 +889,30 @@ Model.prototype.$__version = function(where, delta) { } }; +/*! + * ignore + */ + +function increment() { + this.$__.version = VERSION_ALL; + return this; +} + /** * Signal that we desire an increment of this documents version. * * #### Example: * - * Model.findById(id, function (err, doc) { - * doc.increment(); - * doc.save(function (err) { .. }) - * }) + * const doc = await Model.findById(id); + * doc.increment(); + * await doc.save(); * * @see versionKeys https://mongoosejs.com/docs/guide.html#versionKey * @memberOf Model + * @method increment * @api public */ -function increment() { - this.$__.version = VERSION_ALL; - return this; -} - Model.prototype.increment = increment; /** @@ -937,22 +942,12 @@ Model.prototype.$__where = function _where(where) { * Removes this document from the db. * * #### Example: - * product.remove(function (err, product) { - * if (err) return handleError(err); - * Product.findById(product._id, function (err, product) { - * console.log(product) // null - * }) - * }) - * - * - * As an extra measure of flow control, remove will return a Promise (bound to `fn` if passed) so it could be chained, or hooked to receive errors * - * #### Example: - * product.remove().then(function (product) { - * ... - * }).catch(function (err) { - * assert.ok(err) - * }) + * const product = await product.remove().catch(function (err) { + * assert.ok(err); + * }); + * const foundProduct = await Product.findById(product._id); + * console.log(foundProduct) // null * * @param {Object} [options] * @param {Session} [options.session=null] the [session](https://docs.mongodb.com/manual/reference/server-sessions/) associated with this operation. If not specified, defaults to the [document's associated session](api.html#document_Document-$session). @@ -995,6 +990,7 @@ Model.prototype.delete = Model.prototype.remove; * Removes this document from the db. Equivalent to `.remove()`. * * #### Example: + * * product = await product.deleteOne(); * await Product.findById(product._id); // null * @@ -1104,6 +1100,7 @@ Model.prototype.$model = function $model(name) { * `MyModel.findOne({ answer: 42 }).select({ _id: 1 }).lean()` * * #### Example: + * * await Character.deleteMany({}); * await Character.create({ name: 'Jean-Luc Picard' }); * @@ -1273,7 +1270,7 @@ for (const i in EventEmitter.prototype) { * * #### Example: * - * const eventSchema = new Schema({ thing: { type: 'string', unique: true }}) + * const eventSchema = new Schema({ thing: { type: 'string', unique: true } }) * // This calls `Event.init()` implicitly, so you don't need to call * // `Event.init()` on your own. * const Event = mongoose.model('Event', eventSchema); @@ -1491,7 +1488,7 @@ Model.syncIndexes = function syncIndexes(options, callback) { * Model.syncIndexes(). * * @param {Object} [options] - * @param {Function} callback optional callback + * @param {Function} [callback] optional callback * @returns {Promise} which contains an object, {toDrop, toCreate}, which * are indexes that would be dropped in MongoDB and indexes that would be created in MongoDB. */ @@ -1655,7 +1652,7 @@ Model.listIndexes = function init(callback) { * * #### Example: * - * const eventSchema = new Schema({ thing: { type: 'string', unique: true }}) + * const eventSchema = new Schema({ thing: { type: 'string', unique: true } }) * const Event = mongoose.model('Event', eventSchema); * * Event.on('index', function (err) { @@ -1890,6 +1887,7 @@ Model.discriminators; * .exec(function(err, characters) {}) * * #### Note: + * * Only translate arguments of object type anything else is returned raw * * @param {Object} fields fields/conditions that may contain aliased keys @@ -2386,7 +2384,7 @@ Model.count = function count(conditions, callback) { * * #### Example: * - * Link.distinct('url', { clicks: {$gt: 100}}, function (err, result) { + * Link.distinct('url', { clicks: { $gt: 100 } }, function (err, result) { * if (err) return handleError(err); * * assert(Array.isArray(result)); @@ -2422,7 +2420,7 @@ Model.distinct = function distinct(field, conditions, callback) { * * For example, instead of writing: * - * User.find({age: {$gte: 21, $lte: 65}}, callback); + * User.find({ age: { $gte: 21, $lte: 65 } }, callback); * * we can instead write: * @@ -2476,19 +2474,6 @@ Model.$where = function $where() { * * Finds a matching document, updates it according to the `update` arg, passing any `options`, and returns the found document (if any) to the callback. The query executes if `callback` is passed else a Query object is returned. * - * #### Options: - * - * - `new`: bool - if true, return the modified document rather than the original. defaults to false (changed in 4.0) - * - `upsert`: bool - creates the object if it doesn't exist. defaults to false. - * - `overwrite`: bool - if true, replace the entire document. - * - `fields`: {Object|String} - Field selection. Equivalent to `.select(fields).findOneAndUpdate()` - * - `maxTimeMS`: puts a time limit on the query - requires mongodb >= 2.6.0 - * - `sort`: if multiple docs are found by the conditions, sets the sort order to choose which doc to update - * - `runValidators`: if true, runs [update validators](/docs/validation.html#update-validators) on this command. Update validators validate the update operation against the model's schema. - * - `setDefaultsOnInsert`: `true` by default. If `setDefaultsOnInsert` and `upsert` are true, mongoose will apply the [defaults](https://mongoosejs.com/docs/defaults.html) specified in the model's schema if a new document is created. - * - `rawResult`: if true, returns the [raw result from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/4.3/interfaces/ModifyResult.html) - * - `strict`: overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict) for this update - * * #### Examples: * * A.findOneAndUpdate(conditions, update, options, callback) // executes @@ -2534,6 +2519,13 @@ Model.$where = function $where() { * @param {Boolean} [options.overwrite=false] By default, if you don't include any [update operators](https://docs.mongodb.com/manual/reference/operator/update/) in `update`, Mongoose will wrap `update` in `$set` for you. This prevents you from accidentally overwriting the document. This option tells Mongoose to skip adding `$set`. An alternative to this would be using [Model.findOneAndReplace(conditions, update, options, callback)](https://mongoosejs.com/docs/api/model.html#model_Model.findOneAndReplace). * @param {Boolean} [options.upsert=false] if true, and no documents found, insert a new document * @param {Object|String|String[]} [options.projection=null] optional fields to return, see [`Query.prototype.select()`](#query_Query-select) + * @param {Boolean} [options.new=false] if true, return the modified document rather than the original + * @param {Object|String} [options.fields] Field selection. Equivalent to `.select(fields).findOneAndUpdate()` + * @param {Number} [options.maxTimeMS] puts a time limit on the query - requires mongodb >= 2.6.0 + * @param {Object|String} [options.sort] if multiple docs are found by the conditions, sets the sort order to choose which doc to update. + * @param {Boolean} [options.runValidators] if true, runs [update validators](/docs/validation.html#update-validators) on this command. Update validators validate the update operation against the model's schema + * @param {Boolean} [options.setDefaultsOnInsert=true] If `setDefaultsOnInsert` and `upsert` are true, mongoose will apply the [defaults](https://mongoosejs.com/docs/defaults.html) specified in the model's schema if a new document is created + * @param {Boolean} [options.rawResult] if true, returns the [raw result from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/4.3/interfaces/ModifyResult.html) * @param {Function} [callback] * @return {Query} * @see Tutorial /docs/tutorials/findoneandupdate.html @@ -2614,17 +2606,6 @@ function _decorateUpdateWithVersionKey(update, options, versionKey) { * * - `findOneAndUpdate()` * - * #### Options: - * - * - `new`: bool - true to return the modified document rather than the original. defaults to false - * - `upsert`: bool - creates the object if it doesn't exist. defaults to false. - * - `runValidators`: if true, runs [update validators](/docs/validation.html#update-validators) on this command. Update validators validate the update operation against the model's schema. - * - `setDefaultsOnInsert`: `true` by default. If `setDefaultsOnInsert` and `upsert` are true, mongoose will apply the [defaults](https://mongoosejs.com/docs/defaults.html) specified in the model's schema if a new document is created. - * - `sort`: if multiple docs are found by the conditions, sets the sort order to choose which doc to update - * - `select`: sets the document fields to return - * - `rawResult`: if true, returns the [raw result from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/4.3/interfaces/ModifyResult.html) - * - `strict`: overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict) for this update - * * #### Examples: * * A.findByIdAndUpdate(id, update, options, callback) // executes @@ -2654,11 +2635,9 @@ function _decorateUpdateWithVersionKey(update, options, versionKey) { * If you need full-fledged validation, use the traditional approach of first * retrieving the document. * - * Model.findById(id, function (err, doc) { - * if (err) .. - * doc.name = 'jason bourne'; - * doc.save(callback); - * }); + * const doc = await Model.findById(id) + * doc.name = 'jason bourne'; + * await doc.save(); * * @param {Object|Number|String} id value of `_id` to query by * @param {Object} [update] @@ -2669,6 +2648,13 @@ function _decorateUpdateWithVersionKey(update, options, versionKey) { * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict) * @param {Boolean} [options.timestamps=null] If set to `false` and [schema-level timestamps](/docs/guide.html#timestamps) are enabled, skip timestamps for this update. Note that this allows you to overwrite timestamps. Does nothing if schema-level timestamps are not set. * @param {Boolean} [options.overwrite=false] By default, if you don't include any [update operators](https://docs.mongodb.com/manual/reference/operator/update/) in `update`, Mongoose will wrap `update` in `$set` for you. This prevents you from accidentally overwriting the document. This option tells Mongoose to skip adding `$set`. An alternative to this would be using [Model.findOneAndReplace({ _id: id }, update, options, callback)](https://mongoosejs.com/docs/api/model.html#model_Model.findOneAndReplace). + * @param {Object|String} [options.sort] if multiple docs are found by the conditions, sets the sort order to choose which doc to update. + * @param {Boolean} [options.runValidators] if true, runs [update validators](/docs/validation.html#update-validators) on this command. Update validators validate the update operation against the model's schema + * @param {Boolean} [options.setDefaultsOnInsert=true] If `setDefaultsOnInsert` and `upsert` are true, mongoose will apply the [defaults](https://mongoosejs.com/docs/defaults.html) specified in the model's schema if a new document is created + * @param {Boolean} [options.rawResult] if true, returns the [raw result from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/4.3/interfaces/ModifyResult.html) + * @param {Boolean} [options.upsert=false] if true, and no documents found, insert a new document + * @param {Boolean} [options.new=false] if true, return the modified document rather than the original + * @param {Object|String} [options.select] sets the document fields to return. * @param {Function} [callback] * @return {Query} * @see Model.findOneAndUpdate #model_Model.findOneAndUpdate @@ -2717,15 +2703,6 @@ Model.findByIdAndUpdate = function(id, update, options, callback) { * this distinction is purely pedantic. You should use `findOneAndDelete()` * unless you have a good reason not to. * - * #### Options: - * - * - `sort`: if multiple docs are found by the conditions, sets the sort order to choose which doc to update - * - `maxTimeMS`: puts a time limit on the query - requires mongodb >= 2.6.0 - * - `select`: sets the document fields to return, ex. `{ projection: { _id: 0 } }` - * - `projection`: equivalent to `select` - * - `rawResult`: if true, returns the [raw result from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/4.3/interfaces/ModifyResult.html) - * - `strict`: overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict) for this update - * * #### Examples: * * A.findOneAndDelete(conditions, options, callback) // executes @@ -2740,17 +2717,19 @@ Model.findByIdAndUpdate = function(id, update, options, callback) { * If you need full-fledged validation, use the traditional approach of first * retrieving the document. * - * Model.findById(id, function (err, doc) { - * if (err) .. - * doc.name = 'jason bourne'; - * doc.save(callback); - * }); + * const doc = await Model.findById(id) + * doc.name = 'jason bourne'; + * await doc.save(); * * @param {Object} conditions * @param {Object} [options] optional see [`Query.prototype.setOptions()`](https://mongoosejs.com/docs/api.html#query_Query-setOptions) * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict) * @param {Object|String|String[]} [options.projection=null] optional fields to return, see [`Query.prototype.select()`](#query_Query-select) * @param {ClientSession} [options.session=null] The session associated with this query. See [transactions docs](/docs/transactions.html). + * @param {Boolean} [options.rawResult] if true, returns the [raw result from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/4.3/interfaces/ModifyResult.html) + * @param {Object|String} [options.sort] if multiple docs are found by the conditions, sets the sort order to choose which doc to update. + * @param {Object|String} [options.select] sets the document fields to return. + * @param {Number} [options.maxTimeMS] puts a time limit on the query - requires mongodb >= 2.6.0 * @param {Function} [callback] * @return {Query} * @api public @@ -2830,15 +2809,6 @@ Model.findByIdAndDelete = function(id, options, callback) { * * - `findOneAndReplace()` * - * #### Options: - * - * - `sort`: if multiple docs are found by the conditions, sets the sort order to choose which doc to update - * - `maxTimeMS`: puts a time limit on the query - requires mongodb >= 2.6.0 - * - `select`: sets the document fields to return - * - `projection`: like select, it determines which fields to return, ex. `{ projection: { _id: 0 } }` - * - `rawResult`: if true, returns the [raw result from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/4.3/interfaces/ModifyResult.html) - * - `strict`: overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict) for this update - * * #### Examples: * * A.findOneAndReplace(filter, replacement, options, callback) // executes @@ -2856,6 +2826,10 @@ Model.findByIdAndDelete = function(id, options, callback) { * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict) * @param {Boolean} [options.timestamps=null] If set to `false` and [schema-level timestamps](/docs/guide.html#timestamps) are enabled, skip timestamps for this update. Note that this allows you to overwrite timestamps. Does nothing if schema-level timestamps are not set. * @param {Object|String|String[]} [options.projection=null] optional fields to return, see [`Query.prototype.select()`](#query_Query-select) + * @param {Object|String} [options.sort] if multiple docs are found by the conditions, sets the sort order to choose which doc to update. + * @param {Boolean} [options.rawResult] if true, returns the [raw result from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/4.3/interfaces/ModifyResult.html) + * @param {Object|String} [options.select] sets the document fields to return. + * @param {Number} [options.maxTimeMS] puts a time limit on the query - requires mongodb >= 2.6.0 * @param {Function} [callback] * @return {Query} * @api public @@ -2909,15 +2883,6 @@ Model.findOneAndReplace = function(filter, replacement, options, callback) { * * - `findOneAndRemove()` * - * #### Options: - * - * - `sort`: if multiple docs are found by the conditions, sets the sort order to choose which doc to update - * - `maxTimeMS`: puts a time limit on the query - requires mongodb >= 2.6.0 - * - `select`: sets the document fields to return - * - `projection`: like select, it determines which fields to return, ex. `{ projection: { _id: 0 } }` - * - `rawResult`: if true, returns the [raw result from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/4.3/interfaces/ModifyResult.html) - * - `strict`: overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict) for this update - * * #### Examples: * * A.findOneAndRemove(conditions, options, callback) // executes @@ -2932,17 +2897,19 @@ Model.findOneAndReplace = function(filter, replacement, options, callback) { * If you need full-fledged validation, use the traditional approach of first * retrieving the document. * - * Model.findById(id, function (err, doc) { - * if (err) .. - * doc.name = 'jason bourne'; - * doc.save(callback); - * }); + * const doc = await Model.findById(id); + * doc.name = 'jason bourne'; + * await doc.save(); * * @param {Object} conditions * @param {Object} [options] optional see [`Query.prototype.setOptions()`](https://mongoosejs.com/docs/api.html#query_Query-setOptions) * @param {ClientSession} [options.session=null] The session associated with this query. See [transactions docs](/docs/transactions.html). * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict) * @param {Object|String|String[]} [options.projection=null] optional fields to return, see [`Query.prototype.select()`](#query_Query-select) + * @param {Object|String} [options.sort] if multiple docs are found by the conditions, sets the sort order to choose which doc to update. + * @param {Boolean} [options.rawResult] if true, returns the [raw result from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/4.3/interfaces/ModifyResult.html) + * @param {Object|String} [options.select] sets the document fields to return. + * @param {Number} [options.maxTimeMS] puts a time limit on the query - requires mongodb >= 2.6.0 * @param {Function} [callback] * @return {Query} * @see mongodb https://www.mongodb.org/display/DOCS/findAndModify+Command @@ -2989,13 +2956,6 @@ Model.findOneAndRemove = function(conditions, options, callback) { * * - `findOneAndRemove()` * - * #### Options: - * - * - `sort`: if multiple docs are found by the conditions, sets the sort order to choose which doc to update - * - `select`: sets the document fields to return - * - `rawResult`: if true, returns the [raw result from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/4.3/interfaces/ModifyResult.html) - * - `strict`: overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict) for this update - * * #### Examples: * * A.findByIdAndRemove(id, options, callback) // executes @@ -3009,6 +2969,9 @@ Model.findOneAndRemove = function(conditions, options, callback) { * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict) * @param {ClientSession} [options.session=null] The session associated with this query. See [transactions docs](/docs/transactions.html). * @param {Object|String|String[]} [options.projection=null] optional fields to return, see [`Query.prototype.select()`](#query_Query-select) + * @param {Object|String} [options.sort] if multiple docs are found by the conditions, sets the sort order to choose which doc to update. + * @param {Boolean} [options.rawResult] if true, returns the [raw result from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/4.3/interfaces/ModifyResult.html) + * @param {Object|String} [options.select] sets the document fields to return. * @param {Function} [callback] * @return {Query} * @see Model.findOneAndRemove #model_Model.findOneAndRemove @@ -3858,7 +3821,6 @@ Model.hydrate = function(obj, projection) { * @param {Boolean} [options.timestamps=null] If set to `false` and [schema-level timestamps](/docs/guide.html#timestamps) are enabled, skip timestamps for this update. Does nothing if schema-level timestamps are not set. * @param {Boolean} [options.overwrite=false] By default, if you don't include any [update operators](https://docs.mongodb.com/manual/reference/operator/update/) in `doc`, Mongoose will wrap `doc` in `$set` for you. This prevents you from accidentally overwriting the document. This option tells Mongoose to skip adding `$set`. * @param {Function} [callback] params are (error, [updateWriteOpResult](https://mongodb.github.io/node-mongodb-native/3.6/api/Collection.html#~updateWriteOpResult)) - * @param {Function} [callback] * @return {Query} * @see MongoDB docs https://docs.mongodb.com/manual/reference/command/update/#update-command-output * @see writeOpResult https://mongodb.github.io/node-mongodb-native/3.6/api/Collection.html#~updateWriteOpResult @@ -4024,54 +3986,34 @@ function _update(model, op, conditions, doc, options, callback) { /** * Executes a mapReduce command. * - * `o` is an object specifying all mapReduce options as well as the map and reduce functions. All options are delegated to the driver implementation. See [node-mongodb-native mapReduce() documentation](https://mongodb.github.io/node-mongodb-native/api-generated/collection.html#mapreduce) for more detail about options. + * `opts` is an object specifying all mapReduce options as well as the map and reduce functions. All options are delegated to the driver implementation. See [node-mongodb-native mapReduce() documentation](https://mongodb.github.io/node-mongodb-native/api-generated/collection.html#mapreduce) for more detail about options. * * This function does not trigger any middleware. * * #### Example: * - * const o = {}; + * const opts = {}; * // `map()` and `reduce()` are run on the MongoDB server, not Node.js, * // these functions are converted to strings - * o.map = function () { emit(this.name, 1) }; - * o.reduce = function (k, vals) { return vals.length }; - * User.mapReduce(o, function (err, results) { + * opts.map = function () { emit(this.name, 1) }; + * opts.reduce = function (k, vals) { return vals.length }; + * User.mapReduce(opts, function (err, results) { * console.log(results) * }) * - * #### Other options: - * - * - `query` {Object} query filter object. - * - `sort` {Object} sort input objects using this key - * - `limit` {Number} max number of documents - * - `keeptemp` {Boolean, default:false} keep temporary data - * - `finalize` {Function} finalize function - * - `scope` {Object} scope variables exposed to map/reduce/finalize during execution - * - `jsMode` {Boolean, default:false} it is possible to make the execution stay in JS. Provided in MongoDB > 2.0.X - * - `verbose` {Boolean, default:false} provide statistics on job execution time. - * - `readPreference` {String} - * - `out*` {Object, default: {inline:1}} sets the output target for the map reduce job. - * - * #### * out options: - * - * - `{inline:1}` the results are returned in an array - * - `{replace: 'collectionName'}` add the results to collectionName: the results replace the collection - * - `{reduce: 'collectionName'}` add the results to collectionName: if dups are detected, uses the reducer / finalize functions - * - `{merge: 'collectionName'}` add the results to collectionName: if dups exist the new docs overwrite the old - * - * If `options.out` is set to `replace`, `merge`, or `reduce`, a Model instance is returned that can be used for further querying. Queries run against this model are all executed with the [`lean` option](/docs/tutorials/lean.html); meaning only the js object is returned and no Mongoose magic is applied (getters, setters, etc). + * If `opts.out` is set to `replace`, `merge`, or `reduce`, a Model instance is returned that can be used for further querying. Queries run against this model are all executed with the [`lean` option](/docs/tutorials/lean.html); meaning only the js object is returned and no Mongoose magic is applied (getters, setters, etc). * * #### Example: * - * const o = {}; + * const opts = {}; * // You can also define `map()` and `reduce()` as strings if your * // linter complains about `emit()` not being defined - * o.map = 'function () { emit(this.name, 1) }'; - * o.reduce = 'function (k, vals) { return vals.length }'; - * o.out = { replace: 'createdCollectionNameForResults' } - * o.verbose = true; + * opts.map = 'function () { emit(this.name, 1) }'; + * opts.reduce = 'function (k, vals) { return vals.length }'; + * opts.out = { replace: 'createdCollectionNameForResults' } + * opts.verbose = true; * - * User.mapReduce(o, function (err, model, stats) { + * User.mapReduce(opts, function (err, model, stats) { * console.log('map reduce took %d ms', stats.processtime) * model.find().where('value').gt(10).exec(function (err, docs) { * console.log(docs); @@ -4080,8 +4022,8 @@ function _update(model, op, conditions, doc, options, callback) { * * // `mapReduce()` returns a promise. However, ES6 promises can only * // resolve to exactly one value, - * o.resolveToObject = true; - * const promise = User.mapReduce(o); + * opts.resolveToObject = true; + * const promise = User.mapReduce(opts); * promise.then(function (res) { * const model = res.model; * const stats = res.stats; @@ -4091,14 +4033,28 @@ function _update(model, op, conditions, doc, options, callback) { * console.log(docs); * }).then(null, handleError).end() * - * @param {Object} o an object specifying map-reduce options + * @param {Object} opts an object specifying map-reduce options + * @param {Boolean} [opts.verbose=false] provide statistics on job execution time + * @param {ReadPreference|String} [opts.readPreference] a read-preference string or a read-preference instance + * @param {Boolean} [opts.jsMode=false] it is possible to make the execution stay in JS. Provided in MongoDB > 2.0.X + * @param {Object} [opts.scope] scope variables exposed to map/reduce/finalize during execution + * @param {Function} [opts.finalize] finalize function + * @param {Boolean} [opts.keeptemp=false] keep temporary data + * @param {Number} [opts.limit] max number of documents + * @param {Object} [opts.sort] sort input objects using this key + * @param {Object} [opts.query] query filter object + * @param {Object} [opts.out] sets the output target for the map reduce job + * @param {Number} [opts.out.inline=1] the results are returned in an array + * @param {String} [opts.out.replace] add the results to collectionName: the results replace the collection + * @param {String} [opts.out.reduce] add the results to collectionName: if dups are detected, uses the reducer / finalize functions + * @param {String} [opts.out.merge] add the results to collectionName: if dups exist the new docs overwrite the old * @param {Function} [callback] optional callback * @see https://www.mongodb.org/display/DOCS/MapReduce * @return {Promise} * @api public */ -Model.mapReduce = function mapReduce(o, callback) { +Model.mapReduce = function mapReduce(opts, callback) { _checkContext(this, 'mapReduce'); callback = this.$handleCallbackError(callback); @@ -4111,20 +4067,20 @@ Model.mapReduce = function mapReduce(o, callback) { Model.mapReduce.schema = new Schema({}, opts); } - if (!o.out) o.out = { inline: 1 }; - if (o.verbose !== false) o.verbose = true; + if (!opts.out) opts.out = { inline: 1 }; + if (opts.verbose !== false) opts.verbose = true; - o.map = String(o.map); - o.reduce = String(o.reduce); + opts.map = String(opts.map); + opts.reduce = String(opts.reduce); - if (o.query) { - let q = new this.Query(o.query); + if (opts.query) { + let q = new this.Query(opts.query); q.cast(this); - o.query = q._conditions; + opts.query = q._conditions; q = undefined; } - this.$__collection.mapReduce(null, null, o, (err, res) => { + this.$__collection.mapReduce(null, null, opts, (err, res) => { if (err) { return cb(err); }