mongoose 6.2.1 → 6.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/.eslintrc.json +5 -1
  2. package/.lgtm.yml +3 -0
  3. package/CHANGELOG.md +54 -0
  4. package/dist/browser.umd.js +156 -152
  5. package/index.js +5 -1
  6. package/lib/aggregate.js +22 -27
  7. package/lib/browserDocument.js +1 -1
  8. package/lib/cast/number.js +2 -3
  9. package/lib/cast.js +7 -4
  10. package/lib/connection.js +43 -21
  11. package/lib/cursor/AggregationCursor.js +12 -7
  12. package/lib/cursor/QueryCursor.js +11 -6
  13. package/lib/document.js +58 -72
  14. package/lib/drivers/node-mongodb-native/collection.js +12 -4
  15. package/lib/drivers/node-mongodb-native/connection.js +11 -0
  16. package/lib/error/cast.js +3 -2
  17. package/lib/helpers/clone.js +11 -2
  18. package/lib/helpers/cursor/eachAsync.js +18 -15
  19. package/lib/helpers/document/cleanModifiedSubpaths.js +1 -0
  20. package/lib/helpers/document/compile.js +7 -4
  21. package/lib/helpers/indexes/decorateDiscriminatorIndexOptions.js +14 -0
  22. package/lib/helpers/indexes/getRelatedIndexes.js +59 -0
  23. package/lib/helpers/isAsyncFunction.js +6 -7
  24. package/lib/helpers/populate/assignVals.js +4 -0
  25. package/lib/helpers/printJestWarning.js +2 -2
  26. package/lib/helpers/projection/applyProjection.js +77 -0
  27. package/lib/helpers/projection/hasIncludedChildren.js +36 -0
  28. package/lib/helpers/projection/isExclusive.js +5 -2
  29. package/lib/helpers/projection/isInclusive.js +5 -1
  30. package/lib/helpers/query/cast$expr.js +14 -19
  31. package/lib/helpers/query/hasDollarKeys.js +7 -3
  32. package/lib/helpers/query/isOperator.js +5 -2
  33. package/lib/helpers/schema/getIndexes.js +6 -2
  34. package/lib/index.js +14 -17
  35. package/lib/internal.js +9 -1
  36. package/lib/model.js +159 -153
  37. package/lib/options/SchemaTypeOptions.js +1 -1
  38. package/lib/plugins/trackTransaction.js +1 -1
  39. package/lib/query.js +159 -147
  40. package/lib/queryhelpers.js +8 -28
  41. package/lib/schema/SubdocumentPath.js +5 -4
  42. package/lib/schema/array.js +13 -6
  43. package/lib/schema/buffer.js +1 -1
  44. package/lib/schema/date.js +1 -1
  45. package/lib/schema/decimal128.js +1 -1
  46. package/lib/schema/documentarray.js +9 -7
  47. package/lib/schema/number.js +1 -1
  48. package/lib/schema/objectid.js +1 -1
  49. package/lib/schema/string.js +4 -4
  50. package/lib/schema.js +12 -8
  51. package/lib/schematype.js +12 -14
  52. package/lib/types/ArraySubdocument.js +1 -1
  53. package/lib/types/DocumentArray/index.js +1 -1
  54. package/lib/types/array/index.js +2 -2
  55. package/lib/types/array/methods/index.js +10 -11
  56. package/lib/types/buffer.js +3 -3
  57. package/lib/types/map.js +3 -4
  58. package/lib/utils.js +9 -3
  59. package/package.json +17 -21
  60. package/tsconfig.json +0 -2
  61. package/types/Connection.d.ts +212 -0
  62. package/types/Error.d.ts +129 -0
  63. package/types/PipelineStage.d.ts +272 -0
  64. package/types/index.d.ts +61 -602
  65. package/lib/types/array/ArrayWrapper.js +0 -981
package/lib/model.js CHANGED
@@ -25,6 +25,7 @@ const ParallelSaveError = require('./error/parallelSave');
25
25
  const applyQueryMiddleware = require('./helpers/query/applyQueryMiddleware');
26
26
  const applyHooks = require('./helpers/model/applyHooks');
27
27
  const applyMethods = require('./helpers/model/applyMethods');
28
+ const applyProjection = require('./helpers/projection/applyProjection');
28
29
  const applyStaticHooks = require('./helpers/model/applyStaticHooks');
29
30
  const applyStatics = require('./helpers/model/applyStatics');
30
31
  const applyWriteConcern = require('./helpers/schema/applyWriteConcern');
@@ -42,6 +43,11 @@ const immediate = require('./helpers/immediate');
42
43
  const internalToObjectOptions = require('./options').internalToObjectOptions;
43
44
  const isDefaultIdIndex = require('./helpers/indexes/isDefaultIdIndex');
44
45
  const isIndexEqual = require('./helpers/indexes/isIndexEqual');
46
+ const {
47
+ getRelatedDBIndexes,
48
+ getRelatedSchemaIndexes
49
+ } = require('./helpers/indexes/getRelatedIndexes');
50
+ const decorateDiscriminatorIndexOptions = require('./helpers/indexes/decorateDiscriminatorIndexOptions');
45
51
  const isPathSelectedInclusive = require('./helpers/projection/isPathSelectedInclusive');
46
52
  const leanPopulateMap = require('./helpers/populate/leanPopulateMap');
47
53
  const modifiedPaths = require('./helpers/update/modifiedPaths');
@@ -91,7 +97,7 @@ const saveToObjectOptions = Object.assign({}, internalToObjectOptions, {
91
97
  * @param {Object} doc values for initial set
92
98
  * @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).
93
99
  * @param {Boolean} [skipId=false] optional boolean. If true, mongoose doesn't add an `_id` field to the document.
94
- * @inherits Document http://mongoosejs.com/docs/api/document.html
100
+ * @inherits Document https://mongoosejs.com/docs/api/document.html
95
101
  * @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.
96
102
  * @event `index`: Emitted after `Model#ensureIndexes` completes. If an error occurred it is passed with the event.
97
103
  * @event `index-single-start`: Emitted when an individual index starts within `Model#ensureIndexes`. The fields and options being used to build the index are also passed with the event.
@@ -243,7 +249,7 @@ Model.prototype.$__handleSave = function(options, callback) {
243
249
  let saveOptions = {};
244
250
 
245
251
  applyWriteConcern(this.$__schema, options);
246
- if (typeof options.writeConcern != 'undefined') {
252
+ if (typeof options.writeConcern !== 'undefined') {
247
253
  saveOptions.writeConcern = {};
248
254
  if ('w' in options.writeConcern) {
249
255
  saveOptions.writeConcern.w = options.writeConcern.w;
@@ -345,17 +351,12 @@ Model.prototype.$__handleSave = function(options, callback) {
345
351
  where[key] = val;
346
352
  }
347
353
  }
348
- this.constructor.exists(where, optionsWithCustomValues).
349
- then((documentExists) => {
350
- if (!documentExists) {
351
- const matchedCount = 0;
352
- return callback(null, { $where: where, matchedCount });
353
- }
354
-
355
- const matchedCount = 1;
354
+ this.constructor.exists(where, optionsWithCustomValues)
355
+ .then(documentExists => {
356
+ const matchedCount = !documentExists ? 0 : 1;
356
357
  callback(null, { $where: where, matchedCount });
357
- }).
358
- catch(callback);
358
+ })
359
+ .catch(callback);
359
360
  return;
360
361
  }
361
362
 
@@ -467,7 +468,7 @@ function generateVersionError(doc, modifiedPaths) {
467
468
  *
468
469
  * @param {Object} [options] options optional options
469
470
  * @param {Session} [options.session=null] the [session](https://docs.mongodb.com/manual/reference/server-sessions/) associated with this save operation. If not specified, defaults to the [document's associated session](api.html#document_Document-$session).
470
- * @param {Object} [options.safe] (DEPRECATED) overrides [schema's safe option](http://mongoosejs.com//docs/guide.html#safe). Use the `w` option instead.
471
+ * @param {Object} [options.safe] (DEPRECATED) overrides [schema's safe option](https://mongoosejs.com//docs/guide.html#safe). Use the `w` option instead.
471
472
  * @param {Boolean} [options.validateBeforeSave] set to false to save without validating.
472
473
  * @param {Boolean} [options.validateModifiedOnly=false] if `true`, Mongoose will only validate modified paths, as opposed to modified paths and `required` paths.
473
474
  * @param {Number|String} [options.w] set the [write concern](https://docs.mongodb.com/manual/reference/write-concern/#w-option). Overrides the [schema-level `writeConcern` option](/docs/guide.html#writeConcern)
@@ -479,7 +480,7 @@ function generateVersionError(doc, modifiedPaths) {
479
480
  * @throws {DocumentNotFoundError} if this [save updates an existing document](api.html#document_Document-isNew) but the document doesn't exist in the database. For example, you will get this error if the document is [deleted between when you retrieved the document and when you saved it](documents.html#updating).
480
481
  * @return {Promise|undefined} Returns undefined if used with callback or a Promise otherwise.
481
482
  * @api public
482
- * @see middleware http://mongoosejs.com/docs/middleware.html
483
+ * @see middleware https://mongoosejs.com/docs/middleware.html
483
484
  */
484
485
 
485
486
  Model.prototype.save = function(options, fn) {
@@ -710,7 +711,7 @@ Model.prototype.$__delta = function() {
710
711
  where._id = this._doc._id;
711
712
  // If `_id` is an object, need to depopulate, but also need to be careful
712
713
  // because `_id` can technically be null (see gh-6406)
713
- if (get(where, '_id.$__', null) != null) {
714
+ if ((where && where._id && where._id.$__ || null) != null) {
714
715
  where._id = where._id.toObject({ transform: false, depopulate: true });
715
716
  }
716
717
  for (; d < len; ++d) {
@@ -890,7 +891,7 @@ Model.prototype.$__version = function(where, delta) {
890
891
  * doc.save(function (err) { .. })
891
892
  * })
892
893
  *
893
- * @see versionKeys http://mongoosejs.com/docs/guide.html#versionKey
894
+ * @see versionKeys https://mongoosejs.com/docs/guide.html#versionKey
894
895
  * @api public
895
896
  */
896
897
 
@@ -1086,7 +1087,7 @@ Model.prototype.model = function model(name) {
1086
1087
  * - `findOne()`
1087
1088
  *
1088
1089
  * @param {Object} filter
1089
- * @param {Object} [options] optional see [`Query.prototype.setOptions()`](http://mongoosejs.com/docs/api.html#query_Query-setOptions)
1090
+ * @param {Object} [options] optional see [`Query.prototype.setOptions()`](https://mongoosejs.com/docs/api.html#query_Query-setOptions)
1090
1091
  * @param {Function} [callback] callback
1091
1092
  * @return {Query}
1092
1093
  */
@@ -1159,7 +1160,7 @@ Model.discriminator = function(name, schema, options) {
1159
1160
 
1160
1161
  options = options || {};
1161
1162
  const value = utils.isPOJO(options) ? options.value : options;
1162
- const clone = get(options, 'clone', true);
1163
+ const clone = typeof options.clone === 'boolean' ? options.clone : true;
1163
1164
 
1164
1165
  _checkContext(this, 'discriminator');
1165
1166
 
@@ -1233,7 +1234,7 @@ for (const i in EventEmitter.prototype) {
1233
1234
 
1234
1235
  /**
1235
1236
  * This function is responsible for building [indexes](https://docs.mongodb.com/manual/indexes/),
1236
- * unless [`autoIndex`](http://mongoosejs.com/docs/guide.html#autoIndex) is turned off.
1237
+ * unless [`autoIndex`](https://mongoosejs.com/docs/guide.html#autoIndex) is turned off.
1237
1238
  *
1238
1239
  * Mongoose calls this function automatically when a model is created using
1239
1240
  * [`mongoose.model()`](/docs/api.html#mongoose_Mongoose-model) or
@@ -1338,7 +1339,7 @@ Model.init = function init(callback) {
1338
1339
  * });
1339
1340
  *
1340
1341
  * @api public
1341
- * @param {Object} [options] see [MongoDB driver docs](http://mongodb.github.io/node-mongodb-native/3.1/api/Db.html#createCollection)
1342
+ * @param {Object} [options] see [MongoDB driver docs](https://mongodb.github.io/node-mongodb-native/3.1/api/Db.html#createCollection)
1342
1343
  * @param {Function} [callback]
1343
1344
  * @returns {Promise}
1344
1345
  */
@@ -1354,15 +1355,24 @@ Model.createCollection = function createCollection(options, callback) {
1354
1355
  options = void 0;
1355
1356
  }
1356
1357
 
1357
- const schemaCollation = get(this, ['schema', 'options', 'collation'], null);
1358
+ const schemaCollation = this &&
1359
+ this.schema &&
1360
+ this.schema.options &&
1361
+ this.schema.options.collation || null;
1358
1362
  if (schemaCollation != null) {
1359
1363
  options = Object.assign({ collation: schemaCollation }, options);
1360
1364
  }
1361
- const capped = get(this, ['schema', 'options', 'capped']);
1365
+ const capped = this &&
1366
+ this.schema &&
1367
+ this.schema.options &&
1368
+ this.schema.options.capped;
1362
1369
  if (capped) {
1363
1370
  options = Object.assign({ capped: true }, capped, options);
1364
1371
  }
1365
- const timeseries = get(this, ['schema', 'options', 'timeseries']);
1372
+ const timeseries = this &&
1373
+ this.schema &&
1374
+ this.schema.options &&
1375
+ this.schema.options.timeseries;
1366
1376
  if (timeseries != null) {
1367
1377
  options = Object.assign({ timeseries }, options);
1368
1378
  }
@@ -1388,7 +1398,7 @@ Model.createCollection = function createCollection(options, callback) {
1388
1398
  * the model's schema except the `_id` index, and build any indexes that
1389
1399
  * are in your schema but not in MongoDB.
1390
1400
  *
1391
- * See the [introductory blog post](http://thecodebarbarian.com/whats-new-in-mongoose-5-2-syncindexes)
1401
+ * See the [introductory blog post](https://thecodebarbarian.com/whats-new-in-mongoose-5-2-syncindexes)
1392
1402
  * for more information.
1393
1403
  *
1394
1404
  * ####Example:
@@ -1466,8 +1476,7 @@ Model.diffIndexes = function diffIndexes(options, callback) {
1466
1476
 
1467
1477
  for (const schemaIndex of schemaIndexes) {
1468
1478
  const key = schemaIndex[0];
1469
- const options = _decorateDiscriminatorIndexOptions(this,
1470
- utils.clone(schemaIndex[1]));
1479
+ const options = decorateDiscriminatorIndexOptions(this.schema, utils.clone(schemaIndex[1]));
1471
1480
  if (isIndexEqual(key, options, index)) {
1472
1481
  found = true;
1473
1482
  }
@@ -1480,10 +1489,9 @@ Model.diffIndexes = function diffIndexes(options, callback) {
1480
1489
  // Iterate through the indexes created on the schema and
1481
1490
  // compare against the indexes in mongodb.
1482
1491
  for (const schemaIndex of schemaIndexes) {
1483
- const key = schemaIndex[0];
1484
1492
  let found = false;
1485
- const options = _decorateDiscriminatorIndexOptions(this,
1486
- utils.clone(schemaIndex[1]));
1493
+ const key = schemaIndex[0];
1494
+ const options = decorateDiscriminatorIndexOptions(this.schema, utils.clone(schemaIndex[1]));
1487
1495
  for (const index of indexes) {
1488
1496
  if (isDefaultIdIndex(index)) {
1489
1497
  continue;
@@ -1520,32 +1528,33 @@ Model.cleanIndexes = function cleanIndexes(callback) {
1520
1528
  return this.db.base._promiseOrCallback(callback, cb => {
1521
1529
  const collection = this.$__collection;
1522
1530
 
1523
- this.listIndexes((err, indexes) => {
1531
+ this.listIndexes((err, dbIndexes) => {
1524
1532
  if (err != null) {
1525
1533
  return cb(err);
1526
1534
  }
1527
1535
 
1528
- const schemaIndexes = this.schema.indexes();
1536
+ dbIndexes = getRelatedDBIndexes(this, dbIndexes);
1537
+ const schemaIndexes = getRelatedSchemaIndexes(this, this.schema.indexes());
1538
+
1529
1539
  const toDrop = [];
1530
1540
 
1531
- for (const index of indexes) {
1541
+ for (const dbIndex of dbIndexes) {
1532
1542
  let found = false;
1533
1543
  // Never try to drop `_id` index, MongoDB server doesn't allow it
1534
- if (isDefaultIdIndex(index)) {
1544
+ if (isDefaultIdIndex(dbIndex)) {
1535
1545
  continue;
1536
1546
  }
1537
1547
 
1538
- for (const schemaIndex of schemaIndexes) {
1539
- const key = schemaIndex[0];
1540
- const options = _decorateDiscriminatorIndexOptions(this,
1541
- utils.clone(schemaIndex[1]));
1542
- if (isIndexEqual(key, options, index)) {
1548
+ for (const [schemaIndexKeysObject, schemaIndexOptions] of schemaIndexes) {
1549
+ const options = decorateDiscriminatorIndexOptions(this.schema, utils.clone(schemaIndexOptions));
1550
+
1551
+ if (isIndexEqual(schemaIndexKeysObject, options, dbIndex)) {
1543
1552
  found = true;
1544
1553
  }
1545
1554
  }
1546
1555
 
1547
1556
  if (!found) {
1548
- toDrop.push(index.name);
1557
+ toDrop.push(dbIndex.name);
1549
1558
  }
1550
1559
  }
1551
1560
 
@@ -1658,7 +1667,7 @@ Model.ensureIndexes = function ensureIndexes(options, callback) {
1658
1667
  };
1659
1668
 
1660
1669
  /**
1661
- * Similar to `ensureIndexes()`, except for it uses the [`createIndex`](http://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#createIndex)
1670
+ * Similar to `ensureIndexes()`, except for it uses the [`createIndex`](https://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#createIndex)
1662
1671
  * function.
1663
1672
  *
1664
1673
  * @param {Object} [options] internal options
@@ -1701,7 +1710,7 @@ function _ensureIndexes(model, options, callback) {
1701
1710
  utils.warn('mongoose: Cannot specify a custom index on `_id` for ' +
1702
1711
  'model name "' + model.modelName + '", ' +
1703
1712
  'MongoDB does not allow overwriting the default `_id` index. See ' +
1704
- 'http://bit.ly/mongodb-id-index');
1713
+ 'https://bit.ly/mongodb-id-index');
1705
1714
  }
1706
1715
  }
1707
1716
 
@@ -1724,7 +1733,17 @@ function _ensureIndexes(model, options, callback) {
1724
1733
  const baseSchema = model.schema._baseSchema;
1725
1734
  const baseSchemaIndexes = baseSchema ? baseSchema.indexes() : [];
1726
1735
 
1727
- const create = function() {
1736
+ immediate(function() {
1737
+ // If buffering is off, do this manually.
1738
+ if (options._automatic && !model.collection.collection) {
1739
+ model.collection.addQueue(create, []);
1740
+ } else {
1741
+ create();
1742
+ }
1743
+ });
1744
+
1745
+
1746
+ function create() {
1728
1747
  if (options._automatic) {
1729
1748
  if (model.schema.options.autoIndex === false ||
1730
1749
  (model.schema.options.autoIndex == null && model.db.config.autoIndex === false)) {
@@ -1753,7 +1772,7 @@ function _ensureIndexes(model, options, callback) {
1753
1772
  }
1754
1773
  }
1755
1774
  delete indexOptions._autoIndex;
1756
- _decorateDiscriminatorIndexOptions(model, indexOptions);
1775
+ decorateDiscriminatorIndexOptions(model.schema, indexOptions);
1757
1776
  applyWriteConcern(model.schema, indexOptions);
1758
1777
 
1759
1778
  indexSingleStart(indexFields, options);
@@ -1779,34 +1798,7 @@ function _ensureIndexes(model, options, callback) {
1779
1798
  }
1780
1799
  create();
1781
1800
  }));
1782
- };
1783
-
1784
- immediate(function() {
1785
- // If buffering is off, do this manually.
1786
- if (options._automatic && !model.collection.collection) {
1787
- model.collection.addQueue(create, []);
1788
- } else {
1789
- create();
1790
- }
1791
- });
1792
- }
1793
-
1794
- function _decorateDiscriminatorIndexOptions(model, indexOptions) {
1795
- // If the model is a discriminator and it has a unique index, add a
1796
- // partialFilterExpression by default so the unique index will only apply
1797
- // to that discriminator.
1798
- if (model.baseModelName != null &&
1799
- !('partialFilterExpression' in indexOptions) &&
1800
- !('sparse' in indexOptions)) {
1801
- const value = (
1802
- model.schema.discriminatorMapping &&
1803
- model.schema.discriminatorMapping.value
1804
- ) || model.modelName;
1805
- const discriminatorKey = model.schema.options.discriminatorKey;
1806
-
1807
- indexOptions.partialFilterExpression = { [discriminatorKey]: value };
1808
- }
1809
- return indexOptions;
1801
+ }
1810
1802
  }
1811
1803
 
1812
1804
  /**
@@ -2026,7 +2018,7 @@ Model.remove = function remove(conditions, options, callback) {
2026
2018
  * [middleware docs](/docs/middleware.html#naming) to learn more.
2027
2019
  *
2028
2020
  * @param {Object} conditions
2029
- * @param {Object} [options] optional see [`Query.prototype.setOptions()`](http://mongoosejs.com/docs/api.html#query_Query-setOptions)
2021
+ * @param {Object} [options] optional see [`Query.prototype.setOptions()`](https://mongoosejs.com/docs/api.html#query_Query-setOptions)
2030
2022
  * @param {Function} [callback]
2031
2023
  * @return {Query}
2032
2024
  * @api public
@@ -2069,7 +2061,7 @@ Model.deleteOne = function deleteOne(conditions, options, callback) {
2069
2061
  * [middleware docs](/docs/middleware.html#naming) to learn more.
2070
2062
  *
2071
2063
  * @param {Object} conditions
2072
- * @param {Object} [options] optional see [`Query.prototype.setOptions()`](http://mongoosejs.com/docs/api.html#query_Query-setOptions)
2064
+ * @param {Object} [options] optional see [`Query.prototype.setOptions()`](https://mongoosejs.com/docs/api.html#query_Query-setOptions)
2073
2065
  * @param {Function} [callback]
2074
2066
  * @return {Query}
2075
2067
  * @api public
@@ -2120,8 +2112,8 @@ Model.deleteMany = function deleteMany(conditions, options, callback) {
2120
2112
  * await MyModel.find({ name: /john/i }, null, { skip: 10 }).exec();
2121
2113
  *
2122
2114
  * @param {Object|ObjectId} filter
2123
- * @param {Object|String|Array<String>} [projection] optional fields to return, see [`Query.prototype.select()`](http://mongoosejs.com/docs/api.html#query_Query-select)
2124
- * @param {Object} [options] optional see [`Query.prototype.setOptions()`](http://mongoosejs.com/docs/api.html#query_Query-setOptions)
2115
+ * @param {Object|String|Array<String>} [projection] optional fields to return, see [`Query.prototype.select()`](https://mongoosejs.com/docs/api.html#query_Query-select)
2116
+ * @param {Object} [options] optional see [`Query.prototype.setOptions()`](https://mongoosejs.com/docs/api.html#query_Query-setOptions)
2125
2117
  * @param {Function} [callback]
2126
2118
  * @return {Query}
2127
2119
  * @see field selection #query_Query-select
@@ -2191,7 +2183,7 @@ Model.find = function find(conditions, projection, options, callback) {
2191
2183
  *
2192
2184
  * @param {Any} id value of `_id` to query by
2193
2185
  * @param {Object|String|Array<String>} [projection] optional fields to return, see [`Query.prototype.select()`](#query_Query-select)
2194
- * @param {Object} [options] optional see [`Query.prototype.setOptions()`](http://mongoosejs.com/docs/api.html#query_Query-setOptions)
2186
+ * @param {Object} [options] optional see [`Query.prototype.setOptions()`](https://mongoosejs.com/docs/api.html#query_Query-setOptions)
2195
2187
  * @param {Function} [callback]
2196
2188
  * @return {Query}
2197
2189
  * @see field selection #query_Query-select
@@ -2234,7 +2226,7 @@ Model.findById = function findById(id, projection, options, callback) {
2234
2226
  *
2235
2227
  * @param {Object} [conditions]
2236
2228
  * @param {Object|String|Array<String>} [projection] optional fields to return, see [`Query.prototype.select()`](#query_Query-select)
2237
- * @param {Object} [options] optional see [`Query.prototype.setOptions()`](http://mongoosejs.com/docs/api.html#query_Query-setOptions)
2229
+ * @param {Object} [options] optional see [`Query.prototype.setOptions()`](https://mongoosejs.com/docs/api.html#query_Query-setOptions)
2238
2230
  * @param {Function} [callback]
2239
2231
  * @return {Query}
2240
2232
  * @see field selection #query_Query-select
@@ -2488,9 +2480,9 @@ Model.$where = function $where() {
2488
2480
  * - `maxTimeMS`: puts a time limit on the query - requires mongodb >= 2.6.0
2489
2481
  * - `sort`: if multiple docs are found by the conditions, sets the sort order to choose which doc to update
2490
2482
  * - `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.
2491
- * - `setDefaultsOnInsert`: `true` by default. If `setDefaultsOnInsert` and `upsert` are true, mongoose will apply the [defaults](http://mongoosejs.com/docs/defaults.html) specified in the model's schema if a new document is created.
2492
- * - `rawResult`: if true, returns the [raw result from the MongoDB driver](http://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#findAndModify)
2493
- * - `strict`: overwrites the schema's [strict mode option](http://mongoosejs.com/docs/guide.html#strict) for this update
2483
+ * - `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.
2484
+ * - `rawResult`: if true, returns the [raw result from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#findAndModify)
2485
+ * - `strict`: overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict) for this update
2494
2486
  *
2495
2487
  * ####Examples:
2496
2488
  *
@@ -2528,11 +2520,11 @@ Model.$where = function $where() {
2528
2520
  *
2529
2521
  * @param {Object} [conditions]
2530
2522
  * @param {Object} [update]
2531
- * @param {Object} [options] optional see [`Query.prototype.setOptions()`](http://mongoosejs.com/docs/api.html#query_Query-setOptions)
2523
+ * @param {Object} [options] optional see [`Query.prototype.setOptions()`](https://mongoosejs.com/docs/api.html#query_Query-setOptions)
2532
2524
  * @param {String} [options.returnDocument='before'] Has two possible values, `'before'` and `'after'`. By default, it will return the document before the update was applied.
2533
2525
  * @param {Object} [options.lean] if truthy, mongoose will return the document as a plain JavaScript object rather than a mongoose document. See [`Query.lean()`](/docs/api.html#query_Query-lean) and [the Mongoose lean tutorial](/docs/tutorials/lean.html).
2534
2526
  * @param {ClientSession} [options.session=null] The session associated with this query. See [transactions docs](/docs/transactions.html).
2535
- * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](http://mongoosejs.com/docs/guide.html#strict)
2527
+ * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
2536
2528
  * @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.
2537
2529
  * @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).
2538
2530
  * @param {Boolean} [options.upsert=false] if true, and no documents found, insert a new document
@@ -2540,7 +2532,7 @@ Model.$where = function $where() {
2540
2532
  * @param {Function} [callback]
2541
2533
  * @return {Query}
2542
2534
  * @see Tutorial /docs/tutorials/findoneandupdate.html
2543
- * @see mongodb http://www.mongodb.org/display/DOCS/findAndModify+Command
2535
+ * @see mongodb https://www.mongodb.org/display/DOCS/findAndModify+Command
2544
2536
  * @api public
2545
2537
  */
2546
2538
 
@@ -2588,7 +2580,7 @@ Model.findOneAndUpdate = function(conditions, update, options, callback) {
2588
2580
  */
2589
2581
 
2590
2582
  function _decorateUpdateWithVersionKey(update, options, versionKey) {
2591
- if (!versionKey || !get(options, 'upsert', false)) {
2583
+ if (!versionKey || !(options && options.upsert || false)) {
2592
2584
  return;
2593
2585
  }
2594
2586
 
@@ -2622,11 +2614,11 @@ function _decorateUpdateWithVersionKey(update, options, versionKey) {
2622
2614
  * - `new`: bool - true to return the modified document rather than the original. defaults to false
2623
2615
  * - `upsert`: bool - creates the object if it doesn't exist. defaults to false.
2624
2616
  * - `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.
2625
- * - `setDefaultsOnInsert`: `true` by default. If `setDefaultsOnInsert` and `upsert` are true, mongoose will apply the [defaults](http://mongoosejs.com/docs/defaults.html) specified in the model's schema if a new document is created.
2617
+ * - `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.
2626
2618
  * - `sort`: if multiple docs are found by the conditions, sets the sort order to choose which doc to update
2627
2619
  * - `select`: sets the document fields to return
2628
- * - `rawResult`: if true, returns the [raw result from the MongoDB driver](http://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#findAndModify)
2629
- * - `strict`: overwrites the schema's [strict mode option](http://mongoosejs.com/docs/guide.html#strict) for this update
2620
+ * - `rawResult`: if true, returns the [raw result from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#findAndModify)
2621
+ * - `strict`: overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict) for this update
2630
2622
  *
2631
2623
  * ####Examples:
2632
2624
  *
@@ -2665,17 +2657,17 @@ function _decorateUpdateWithVersionKey(update, options, versionKey) {
2665
2657
  *
2666
2658
  * @param {Object|Number|String} id value of `_id` to query by
2667
2659
  * @param {Object} [update]
2668
- * @param {Object} [options] optional see [`Query.prototype.setOptions()`](http://mongoosejs.com/docs/api.html#query_Query-setOptions)
2660
+ * @param {Object} [options] optional see [`Query.prototype.setOptions()`](https://mongoosejs.com/docs/api.html#query_Query-setOptions)
2669
2661
  * @param {String} [options.returnDocument='before'] Has two possible values, `'before'` and `'after'`. By default, it will return the document before the update was applied.
2670
2662
  * @param {Object} [options.lean] if truthy, mongoose will return the document as a plain JavaScript object rather than a mongoose document. See [`Query.lean()`](/docs/api.html#query_Query-lean) and [the Mongoose lean tutorial](/docs/tutorials/lean.html).
2671
2663
  * @param {ClientSession} [options.session=null] The session associated with this query. See [transactions docs](/docs/transactions.html).
2672
- * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](http://mongoosejs.com/docs/guide.html#strict)
2664
+ * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
2673
2665
  * @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.
2674
2666
  * @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).
2675
2667
  * @param {Function} [callback]
2676
2668
  * @return {Query}
2677
2669
  * @see Model.findOneAndUpdate #model_Model.findOneAndUpdate
2678
- * @see mongodb http://www.mongodb.org/display/DOCS/findAndModify+Command
2670
+ * @see mongodb https://www.mongodb.org/display/DOCS/findAndModify+Command
2679
2671
  * @api public
2680
2672
  */
2681
2673
 
@@ -2726,8 +2718,8 @@ Model.findByIdAndUpdate = function(id, update, options, callback) {
2726
2718
  * - `maxTimeMS`: puts a time limit on the query - requires mongodb >= 2.6.0
2727
2719
  * - `select`: sets the document fields to return, ex. `{ projection: { _id: 0 } }`
2728
2720
  * - `projection`: equivalent to `select`
2729
- * - `rawResult`: if true, returns the [raw result from the MongoDB driver](http://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#findAndModify)
2730
- * - `strict`: overwrites the schema's [strict mode option](http://mongoosejs.com/docs/guide.html#strict) for this update
2721
+ * - `rawResult`: if true, returns the [raw result from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#findAndModify)
2722
+ * - `strict`: overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict) for this update
2731
2723
  *
2732
2724
  * ####Examples:
2733
2725
  *
@@ -2750,8 +2742,8 @@ Model.findByIdAndUpdate = function(id, update, options, callback) {
2750
2742
  * });
2751
2743
  *
2752
2744
  * @param {Object} conditions
2753
- * @param {Object} [options] optional see [`Query.prototype.setOptions()`](http://mongoosejs.com/docs/api.html#query_Query-setOptions)
2754
- * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](http://mongoosejs.com/docs/guide.html#strict)
2745
+ * @param {Object} [options] optional see [`Query.prototype.setOptions()`](https://mongoosejs.com/docs/api.html#query_Query-setOptions)
2746
+ * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
2755
2747
  * @param {Object|String|Array<String>} [options.projection=null] optional fields to return, see [`Query.prototype.select()`](#query_Query-select)
2756
2748
  * @param {ClientSession} [options.session=null] The session associated with this query. See [transactions docs](/docs/transactions.html).
2757
2749
  * @param {Function} [callback]
@@ -2798,12 +2790,12 @@ Model.findOneAndDelete = function(conditions, options, callback) {
2798
2790
  * - `findOneAndDelete()`
2799
2791
  *
2800
2792
  * @param {Object|Number|String} id value of `_id` to query by
2801
- * @param {Object} [options] optional see [`Query.prototype.setOptions()`](http://mongoosejs.com/docs/api.html#query_Query-setOptions)
2802
- * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](http://mongoosejs.com/docs/guide.html#strict)
2793
+ * @param {Object} [options] optional see [`Query.prototype.setOptions()`](https://mongoosejs.com/docs/api.html#query_Query-setOptions)
2794
+ * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
2803
2795
  * @param {Function} [callback]
2804
2796
  * @return {Query}
2805
2797
  * @see Model.findOneAndRemove #model_Model.findOneAndRemove
2806
- * @see mongodb http://www.mongodb.org/display/DOCS/findAndModify+Command
2798
+ * @see mongodb https://www.mongodb.org/display/DOCS/findAndModify+Command
2807
2799
  */
2808
2800
 
2809
2801
  Model.findByIdAndDelete = function(id, options, callback) {
@@ -2839,8 +2831,8 @@ Model.findByIdAndDelete = function(id, options, callback) {
2839
2831
  * - `maxTimeMS`: puts a time limit on the query - requires mongodb >= 2.6.0
2840
2832
  * - `select`: sets the document fields to return
2841
2833
  * - `projection`: like select, it determines which fields to return, ex. `{ projection: { _id: 0 } }`
2842
- * - `rawResult`: if true, returns the [raw result from the MongoDB driver](http://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#findAndModify)
2843
- * - `strict`: overwrites the schema's [strict mode option](http://mongoosejs.com/docs/guide.html#strict) for this update
2834
+ * - `rawResult`: if true, returns the [raw result from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#findAndModify)
2835
+ * - `strict`: overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict) for this update
2844
2836
  *
2845
2837
  * ####Examples:
2846
2838
  *
@@ -2852,11 +2844,11 @@ Model.findByIdAndDelete = function(id, options, callback) {
2852
2844
  *
2853
2845
  * @param {Object} filter Replace the first document that matches this filter
2854
2846
  * @param {Object} [replacement] Replace with this document
2855
- * @param {Object} [options] optional see [`Query.prototype.setOptions()`](http://mongoosejs.com/docs/api.html#query_Query-setOptions)
2847
+ * @param {Object} [options] optional see [`Query.prototype.setOptions()`](https://mongoosejs.com/docs/api.html#query_Query-setOptions)
2856
2848
  * @param {String} [options.returnDocument='before'] Has two possible values, `'before'` and `'after'`. By default, it will return the document before the update was applied.
2857
2849
  * @param {Object} [options.lean] if truthy, mongoose will return the document as a plain JavaScript object rather than a mongoose document. See [`Query.lean()`](/docs/api.html#query_Query-lean) and [the Mongoose lean tutorial](/docs/tutorials/lean.html).
2858
2850
  * @param {ClientSession} [options.session=null] The session associated with this query. See [transactions docs](/docs/transactions.html).
2859
- * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](http://mongoosejs.com/docs/guide.html#strict)
2851
+ * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
2860
2852
  * @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.
2861
2853
  * @param {Object|String|Array<String>} [options.projection=null] optional fields to return, see [`Query.prototype.select()`](#query_Query-select)
2862
2854
  * @param {Function} [callback]
@@ -2916,8 +2908,8 @@ Model.findOneAndReplace = function(filter, replacement, options, callback) {
2916
2908
  * - `maxTimeMS`: puts a time limit on the query - requires mongodb >= 2.6.0
2917
2909
  * - `select`: sets the document fields to return
2918
2910
  * - `projection`: like select, it determines which fields to return, ex. `{ projection: { _id: 0 } }`
2919
- * - `rawResult`: if true, returns the [raw result from the MongoDB driver](http://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#findAndModify)
2920
- * - `strict`: overwrites the schema's [strict mode option](http://mongoosejs.com/docs/guide.html#strict) for this update
2911
+ * - `rawResult`: if true, returns the [raw result from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#findAndModify)
2912
+ * - `strict`: overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict) for this update
2921
2913
  *
2922
2914
  * ####Examples:
2923
2915
  *
@@ -2940,13 +2932,13 @@ Model.findOneAndReplace = function(filter, replacement, options, callback) {
2940
2932
  * });
2941
2933
  *
2942
2934
  * @param {Object} conditions
2943
- * @param {Object} [options] optional see [`Query.prototype.setOptions()`](http://mongoosejs.com/docs/api.html#query_Query-setOptions)
2935
+ * @param {Object} [options] optional see [`Query.prototype.setOptions()`](https://mongoosejs.com/docs/api.html#query_Query-setOptions)
2944
2936
  * @param {ClientSession} [options.session=null] The session associated with this query. See [transactions docs](/docs/transactions.html).
2945
- * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](http://mongoosejs.com/docs/guide.html#strict)
2937
+ * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
2946
2938
  * @param {Object|String|Array<String>} [options.projection=null] optional fields to return, see [`Query.prototype.select()`](#query_Query-select)
2947
2939
  * @param {Function} [callback]
2948
2940
  * @return {Query}
2949
- * @see mongodb http://www.mongodb.org/display/DOCS/findAndModify+Command
2941
+ * @see mongodb https://www.mongodb.org/display/DOCS/findAndModify+Command
2950
2942
  * @api public
2951
2943
  */
2952
2944
 
@@ -2994,8 +2986,8 @@ Model.findOneAndRemove = function(conditions, options, callback) {
2994
2986
  *
2995
2987
  * - `sort`: if multiple docs are found by the conditions, sets the sort order to choose which doc to update
2996
2988
  * - `select`: sets the document fields to return
2997
- * - `rawResult`: if true, returns the [raw result from the MongoDB driver](http://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#findAndModify)
2998
- * - `strict`: overwrites the schema's [strict mode option](http://mongoosejs.com/docs/guide.html#strict) for this update
2989
+ * - `rawResult`: if true, returns the [raw result from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#findAndModify)
2990
+ * - `strict`: overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict) for this update
2999
2991
  *
3000
2992
  * ####Examples:
3001
2993
  *
@@ -3006,14 +2998,14 @@ Model.findOneAndRemove = function(conditions, options, callback) {
3006
2998
  * A.findByIdAndRemove() // returns Query
3007
2999
  *
3008
3000
  * @param {Object|Number|String} id value of `_id` to query by
3009
- * @param {Object} [options] optional see [`Query.prototype.setOptions()`](http://mongoosejs.com/docs/api.html#query_Query-setOptions)
3010
- * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](http://mongoosejs.com/docs/guide.html#strict)
3001
+ * @param {Object} [options] optional see [`Query.prototype.setOptions()`](https://mongoosejs.com/docs/api.html#query_Query-setOptions)
3002
+ * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
3011
3003
  * @param {ClientSession} [options.session=null] The session associated with this query. See [transactions docs](/docs/transactions.html).
3012
3004
  * @param {Object|String|Array<String>} [options.projection=null] optional fields to return, see [`Query.prototype.select()`](#query_Query-select)
3013
3005
  * @param {Function} [callback]
3014
3006
  * @return {Query}
3015
3007
  * @see Model.findOneAndRemove #model_Model.findOneAndRemove
3016
- * @see mongodb http://www.mongodb.org/display/DOCS/findAndModify+Command
3008
+ * @see mongodb https://www.mongodb.org/display/DOCS/findAndModify+Command
3017
3009
  */
3018
3010
 
3019
3011
  Model.findByIdAndRemove = function(id, options, callback) {
@@ -3158,7 +3150,7 @@ Model.create = function create(doc, options, callback) {
3158
3150
  return cb(firstError, savedDocs);
3159
3151
  }
3160
3152
 
3161
- if (doc instanceof Array) {
3153
+ if (Array.isArray(doc)) {
3162
3154
  cb(null, savedDocs);
3163
3155
  } else {
3164
3156
  cb.apply(this, [null].concat(savedDocs));
@@ -3204,7 +3196,7 @@ Model.create = function create(doc, options, callback) {
3204
3196
  * await doc.remove();
3205
3197
  *
3206
3198
  * @param {Array} [pipeline]
3207
- * @param {Object} [options] see the [mongodb driver options](http://mongodb.github.io/node-mongodb-native/3.0/api/Collection.html#watch)
3199
+ * @param {Object} [options] see the [mongodb driver options](https://mongodb.github.io/node-mongodb-native/3.0/api/Collection.html#watch)
3208
3200
  * @return {ChangeStream} mongoose-specific change stream wrapper, inherits from EventEmitter
3209
3201
  * @api public
3210
3202
  */
@@ -3235,7 +3227,7 @@ Model.watch = function(pipeline, options) {
3235
3227
  /**
3236
3228
  * _Requires MongoDB >= 3.6.0._ Starts a [MongoDB session](https://docs.mongodb.com/manual/release-notes/3.6/#client-sessions)
3237
3229
  * for benefits like causal consistency, [retryable writes](https://docs.mongodb.com/manual/core/retryable-writes/),
3238
- * and [transactions](http://thecodebarbarian.com/a-node-js-perspective-on-mongodb-4-transactions.html).
3230
+ * and [transactions](https://thecodebarbarian.com/a-node-js-perspective-on-mongodb-4-transactions.html).
3239
3231
  *
3240
3232
  * Calling `MyModel.startSession()` is equivalent to calling `MyModel.db.startSession()`.
3241
3233
  *
@@ -3252,7 +3244,7 @@ Model.watch = function(pipeline, options) {
3252
3244
  * // secondary that is experiencing replication lag.
3253
3245
  * doc = await Person.findOne({ name: 'Ned Stark' }, null, { session, readPreference: 'secondary' });
3254
3246
  *
3255
- * @param {Object} [options] see the [mongodb driver options](http://mongodb.github.io/node-mongodb-native/3.0/api/MongoClient.html#startSession)
3247
+ * @param {Object} [options] see the [mongodb driver options](https://mongodb.github.io/node-mongodb-native/3.0/api/MongoClient.html#startSession)
3256
3248
  * @param {Boolean} [options.causalConsistency=true] set to false to disable causal consistency
3257
3249
  * @param {Function} [callback]
3258
3250
  * @return {Promise<ClientSession>} promise that resolves to a MongoDB driver `ClientSession`
@@ -3288,9 +3280,9 @@ Model.startSession = function() {
3288
3280
  * Movies.insertMany(arr, function(error, docs) {});
3289
3281
  *
3290
3282
  * @param {Array|Object|*} doc(s)
3291
- * @param {Object} [options] see the [mongodb driver options](http://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#insertMany)
3283
+ * @param {Object} [options] see the [mongodb driver options](https://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#insertMany)
3292
3284
  * @param {Boolean} [options.ordered = true] if true, will fail fast on the first error encountered. If false, will insert all the documents it can and report errors later. An `insertMany()` with `ordered = false` is called an "unordered" `insertMany()`.
3293
- * @param {Boolean} [options.rawResult = false] if false, the returned promise resolves to the documents that passed mongoose document validation. If `true`, will return the [raw result from the MongoDB driver](http://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#~insertWriteOpCallback) with a `mongoose` property that contains `validationErrors` if this is an unordered `insertMany`.
3285
+ * @param {Boolean} [options.rawResult = false] if false, the returned promise resolves to the documents that passed mongoose document validation. If `true`, will return the [raw result from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#~insertWriteOpCallback) with a `mongoose` property that contains `validationErrors` if this is an unordered `insertMany`.
3294
3286
  * @param {Boolean} [options.lean = false] if `true`, skips hydrating and validating the documents. This option is useful if you need the extra performance, but Mongoose won't validate the documents before inserting.
3295
3287
  * @param {Number} [options.limit = null] this limits the number of documents being processed (validation/casting) by mongoose in parallel, this does **NOT** send the documents in batches to MongoDB. Use this option if you're processing a large number of documents and your app is running out of memory.
3296
3288
  * @param {String|Object|Array} [options.populate = null] populates the result documents. This option is a no-op if `rawResult` is set.
@@ -3327,10 +3319,10 @@ Model.$__insertMany = function(arr, options, callback) {
3327
3319
  }
3328
3320
  callback = callback || utils.noop;
3329
3321
  options = options || {};
3330
- const limit = get(options, 'limit', 1000);
3331
- const rawResult = get(options, 'rawResult', false);
3332
- const ordered = get(options, 'ordered', true);
3333
- const lean = get(options, 'lean', false);
3322
+ const limit = options.limit || 1000;
3323
+ const rawResult = !!options.rawResult;
3324
+ const ordered = typeof options.ordered === 'boolean' ? options.ordered : true;
3325
+ const lean = !!options.lean;
3334
3326
 
3335
3327
  if (!Array.isArray(arr)) {
3336
3328
  arr = [arr];
@@ -3408,12 +3400,12 @@ Model.$__insertMany = function(arr, options, callback) {
3408
3400
  // `writeErrors` is a property reported by the MongoDB driver,
3409
3401
  // just not if there's only 1 error.
3410
3402
  if (error.writeErrors == null &&
3411
- get(error, 'result.result.writeErrors') != null) {
3403
+ (error.result && error.result.result && error.result.result.writeErrors) != null) {
3412
3404
  error.writeErrors = error.result.result.writeErrors;
3413
3405
  }
3414
3406
 
3415
3407
  // `insertedDocs` is a Mongoose-specific property
3416
- const erroredIndexes = new Set(get(error, 'writeErrors', []).map(err => err.index));
3408
+ const erroredIndexes = new Set((error && error.writeErrors || []).map(err => err.index));
3417
3409
 
3418
3410
  let firstErroredIndex = -1;
3419
3411
  error.insertedDocs = docAttributes.
@@ -3500,7 +3492,7 @@ function _setIsNew(doc, val) {
3500
3492
  *
3501
3493
  * This function does **not** trigger any middleware, neither `save()`, nor `update()`.
3502
3494
  * If you need to trigger
3503
- * `save()` middleware for every document use [`create()`](http://mongoosejs.com/docs/api.html#model_Model.create) instead.
3495
+ * `save()` middleware for every document use [`create()`](https://mongoosejs.com/docs/api.html#model_Model.create) instead.
3504
3496
  *
3505
3497
  * ####Example:
3506
3498
  *
@@ -3524,9 +3516,7 @@ function _setIsNew(doc, val) {
3524
3516
  * },
3525
3517
  * {
3526
3518
  * deleteOne: {
3527
- * {
3528
- * filter: { name: 'Eddard Stark' }
3529
- * }
3519
+ * filter: { name: 'Eddard Stark' }
3530
3520
  * }
3531
3521
  * }
3532
3522
  * ]).then(res => {
@@ -3571,7 +3561,7 @@ function _setIsNew(doc, val) {
3571
3561
  * @param {Boolean} [options.bypassDocumentValidation=false] If true, disable [MongoDB server-side schema validation](https://docs.mongodb.com/manual/core/schema-validation/) for all writes in this bulk.
3572
3562
  * @param {Boolean} [options.strict=null] Overwrites the [`strict` option](/docs/guide.html#strict) on schema. If false, allows filtering and writing fields not defined in the schema for all writes in this bulk.
3573
3563
  * @param {Function} [callback] callback `function(error, bulkWriteOpResult) {}`
3574
- * @return {Promise} resolves to a [`BulkWriteOpResult`](http://mongodb.github.io/node-mongodb-native/3.1/api/Collection.html#~BulkWriteOpResult) if the operation succeeds
3564
+ * @return {Promise} resolves to a [`BulkWriteOpResult`](https://mongodb.github.io/node-mongodb-native/3.1/api/Collection.html#~BulkWriteOpResult) if the operation succeeds
3575
3565
  * @api public
3576
3566
  */
3577
3567
 
@@ -3634,7 +3624,7 @@ Model.bulkSave = function(documents, options) {
3634
3624
  .then(() => documents.map(buildSuccessfulWriteHandlerPromise))
3635
3625
  .then(() => bulkWriteResultPromise)
3636
3626
  .catch((err) => {
3637
- if (!get(err, 'writeErrors.length')) {
3627
+ if (!(err && err.writeErrors && err.writeErrors.length)) {
3638
3628
  throw err;
3639
3629
  }
3640
3630
  return Promise.all(
@@ -3774,6 +3764,13 @@ Model.buildBulkWriteOperations = function buildBulkWriteOperations(documents, op
3774
3764
  Model.hydrate = function(obj, projection) {
3775
3765
  _checkContext(this, 'hydrate');
3776
3766
 
3767
+ if (projection != null) {
3768
+ if (obj != null && obj.$__ != null) {
3769
+ obj = obj.toObject(internalToObjectOptions);
3770
+ }
3771
+ obj = applyProjection(obj, projection);
3772
+ }
3773
+
3777
3774
  const document = require('./queryhelpers').createModel(this, obj, projection);
3778
3775
  document.$init(obj);
3779
3776
  return document;
@@ -3805,7 +3802,7 @@ Model.hydrate = function(obj, projection) {
3805
3802
  * - `writeConcern` (object): sets the [write concern](https://docs.mongodb.com/manual/reference/write-concern/) for replica sets. Overrides the [schema-level write concern](/docs/guide.html#writeConcern)
3806
3803
  * - `multi` (boolean): whether multiple documents should be updated (false)
3807
3804
  * - `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.
3808
- * - `setDefaultsOnInsert` (boolean): if this and `upsert` are true, mongoose will apply the [defaults](http://mongoosejs.com/docs/defaults.html) specified in the model's schema if a new document is created. This option only works on MongoDB >= 2.4 because it relies on [MongoDB's `$setOnInsert` operator](https://docs.mongodb.org/v2.4/reference/operator/update/setOnInsert/).
3805
+ * - `setDefaultsOnInsert` (boolean): if this 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. This option only works on MongoDB >= 2.4 because it relies on [MongoDB's `$setOnInsert` operator](https://docs.mongodb.org/v2.4/reference/operator/update/setOnInsert/).
3809
3806
  * - `timestamps` (boolean): 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.
3810
3807
  * - `overwrite` (boolean): disables update-only mode, allowing you to overwrite the doc (false)
3811
3808
  *
@@ -3836,8 +3833,8 @@ Model.hydrate = function(obj, projection) {
3836
3833
  * Be careful to not use an existing model instance for the update clause (this won't work and can cause weird behavior like infinite loops). Also, ensure that the update clause does not have an _id property, which causes Mongo to return a "Mod on _id not allowed" error.
3837
3834
  *
3838
3835
  * @deprecated
3839
- * @see strict http://mongoosejs.com/docs/guide.html#strict
3840
- * @see response http://docs.mongodb.org/v2.6/reference/command/update/#output
3836
+ * @see strict https://mongoosejs.com/docs/guide.html#strict
3837
+ * @see response https://docs.mongodb.org/v2.6/reference/command/update/#output
3841
3838
  * @param {Object} filter
3842
3839
  * @param {Object} doc
3843
3840
  * @param {Object} [options] optional see [`Query.prototype.setOptions()`](/docs/api.html#query_Query-setOptions)
@@ -3846,7 +3843,7 @@ Model.hydrate = function(obj, projection) {
3846
3843
  * @param {Object} [options.writeConcern=null] sets the [write concern](https://docs.mongodb.com/manual/reference/write-concern/) for replica sets. Overrides the [schema-level write concern](/docs/guide.html#writeConcern)
3847
3844
  * @param {Boolean} [options.multi=false] whether multiple documents should be updated or just the first one that matches `filter`.
3848
3845
  * @param {Boolean} [options.runValidators=false] if true, runs [update validators](/docs/validation.html#update-validators) on this command. Update validators validate the update operation against the model's schema.
3849
- * @param {Boolean} [options.setDefaultsOnInsert=false] `true` by default. If `setDefaultsOnInsert` and `upsert` are true, mongoose will apply the [defaults](http://mongoosejs.com/docs/defaults.html) specified in the model's schema if a new document is created.
3846
+ * @param {Boolean} [options.setDefaultsOnInsert=false] `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.
3850
3847
  * @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.
3851
3848
  * @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`.
3852
3849
  * @param {Function} [callback] params are (error, [updateWriteOpResult](https://mongodb.github.io/node-mongodb-native/3.6/api/Collection.html#~updateWriteOpResult))
@@ -3886,8 +3883,8 @@ Model.update = function update(conditions, doc, options, callback) {
3886
3883
  *
3887
3884
  * @param {Object} filter
3888
3885
  * @param {Object|Array} update
3889
- * @param {Object} [options] optional see [`Query.prototype.setOptions()`](http://mongoosejs.com/docs/api.html#query_Query-setOptions)
3890
- * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](http://mongoosejs.com/docs/guide.html#strict)
3886
+ * @param {Object} [options] optional see [`Query.prototype.setOptions()`](https://mongoosejs.com/docs/api.html#query_Query-setOptions)
3887
+ * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
3891
3888
  * @param {Boolean} [options.upsert=false] if true, and no documents found, insert a new document
3892
3889
  * @param {Object} [options.writeConcern=null] sets the [write concern](https://docs.mongodb.com/manual/reference/write-concern/) for replica sets. Overrides the [schema-level write concern](/docs/guide.html#writeConcern)
3893
3890
  * @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.
@@ -3895,7 +3892,7 @@ Model.update = function update(conditions, doc, options, callback) {
3895
3892
  * @return {Query}
3896
3893
  * @see Query docs https://mongoosejs.com/docs/queries.html
3897
3894
  * @see MongoDB docs https://docs.mongodb.com/manual/reference/command/update/#update-command-output
3898
- * @see writeOpResult http://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#~WriteOpResult
3895
+ * @see writeOpResult https://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#~WriteOpResult
3899
3896
  * @api public
3900
3897
  */
3901
3898
 
@@ -3926,8 +3923,8 @@ Model.updateMany = function updateMany(conditions, doc, options, callback) {
3926
3923
  *
3927
3924
  * @param {Object} filter
3928
3925
  * @param {Object|Array} update
3929
- * @param {Object} [options] optional see [`Query.prototype.setOptions()`](http://mongoosejs.com/docs/api.html#query_Query-setOptions)
3930
- * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](http://mongoosejs.com/docs/guide.html#strict)
3926
+ * @param {Object} [options] optional see [`Query.prototype.setOptions()`](https://mongoosejs.com/docs/api.html#query_Query-setOptions)
3927
+ * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
3931
3928
  * @param {Boolean} [options.upsert=false] if true, and no documents found, insert a new document
3932
3929
  * @param {Object} [options.writeConcern=null] sets the [write concern](https://docs.mongodb.com/manual/reference/write-concern/) for replica sets. Overrides the [schema-level write concern](/docs/guide.html#writeConcern)
3933
3930
  * @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.
@@ -3935,7 +3932,7 @@ Model.updateMany = function updateMany(conditions, doc, options, callback) {
3935
3932
  * @return {Query}
3936
3933
  * @see Query docs https://mongoosejs.com/docs/queries.html
3937
3934
  * @see MongoDB docs https://docs.mongodb.com/manual/reference/command/update/#update-command-output
3938
- * @see writeOpResult http://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#~WriteOpResult
3935
+ * @see writeOpResult https://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#~WriteOpResult
3939
3936
  * @api public
3940
3937
  */
3941
3938
 
@@ -3963,15 +3960,15 @@ Model.updateOne = function updateOne(conditions, doc, options, callback) {
3963
3960
  *
3964
3961
  * @param {Object} filter
3965
3962
  * @param {Object} doc
3966
- * @param {Object} [options] optional see [`Query.prototype.setOptions()`](http://mongoosejs.com/docs/api.html#query_Query-setOptions)
3967
- * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](http://mongoosejs.com/docs/guide.html#strict)
3963
+ * @param {Object} [options] optional see [`Query.prototype.setOptions()`](https://mongoosejs.com/docs/api.html#query_Query-setOptions)
3964
+ * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
3968
3965
  * @param {Boolean} [options.upsert=false] if true, and no documents found, insert a new document
3969
3966
  * @param {Object} [options.writeConcern=null] sets the [write concern](https://docs.mongodb.com/manual/reference/write-concern/) for replica sets. Overrides the [schema-level write concern](/docs/guide.html#writeConcern)
3970
3967
  * @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.
3971
3968
  * @param {Function} [callback] `function(error, res) {}` where `res` has 3 properties: `n`, `nModified`, `ok`.
3972
3969
  * @return {Query}
3973
3970
  * @see Query docs https://mongoosejs.com/docs/queries.html
3974
- * @see writeOpResult http://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#~WriteOpResult
3971
+ * @see writeOpResult https://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#~WriteOpResult
3975
3972
  * @return {Query}
3976
3973
  * @api public
3977
3974
  */
@@ -3979,7 +3976,7 @@ Model.updateOne = function updateOne(conditions, doc, options, callback) {
3979
3976
  Model.replaceOne = function replaceOne(conditions, doc, options, callback) {
3980
3977
  _checkContext(this, 'replaceOne');
3981
3978
 
3982
- const versionKey = get(this, 'schema.options.versionKey', null);
3979
+ const versionKey = this && this.schema && this.schema.options && this.schema.options.versionKey || null;
3983
3980
  if (versionKey && !doc[versionKey]) {
3984
3981
  doc[versionKey] = 0;
3985
3982
  }
@@ -4004,7 +4001,10 @@ function _update(model, op, conditions, doc, options, callback) {
4004
4001
  }
4005
4002
  options = typeof options === 'function' ? options : utils.clone(options);
4006
4003
 
4007
- const versionKey = get(model, 'schema.options.versionKey', null);
4004
+ const versionKey = model &&
4005
+ model.schema &&
4006
+ model.schema.options &&
4007
+ model.schema.options.versionKey || null;
4008
4008
  _decorateUpdateWithVersionKey(doc, options, versionKey);
4009
4009
 
4010
4010
  return mq[op](conditions, doc, options, callback);
@@ -4013,7 +4013,7 @@ function _update(model, op, conditions, doc, options, callback) {
4013
4013
  /**
4014
4014
  * Executes a mapReduce command.
4015
4015
  *
4016
- * `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](http://mongodb.github.io/node-mongodb-native/api-generated/collection.html#mapreduce) for more detail about options.
4016
+ * `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.
4017
4017
  *
4018
4018
  * This function does not trigger any middleware.
4019
4019
  *
@@ -4082,7 +4082,7 @@ function _update(model, op, conditions, doc, options, callback) {
4082
4082
  *
4083
4083
  * @param {Object} o an object specifying map-reduce options
4084
4084
  * @param {Function} [callback] optional callback
4085
- * @see http://www.mongodb.org/display/DOCS/MapReduce
4085
+ * @see https://www.mongodb.org/display/DOCS/MapReduce
4086
4086
  * @return {Promise}
4087
4087
  * @api public
4088
4088
  */
@@ -4135,7 +4135,7 @@ Model.mapReduce = function mapReduce(o, callback) {
4135
4135
  };
4136
4136
 
4137
4137
  /**
4138
- * Performs [aggregations](http://docs.mongodb.org/manual/applications/aggregation/) on the models collection.
4138
+ * Performs [aggregations](https://docs.mongodb.org/manual/applications/aggregation/) on the models collection.
4139
4139
  *
4140
4140
  * If a `callback` is passed, the `aggregate` is executed and a `Promise` is returned. If a callback is not passed, the `aggregate` itself is returned.
4141
4141
  *
@@ -4169,10 +4169,10 @@ Model.mapReduce = function mapReduce(o, callback) {
4169
4169
  *
4170
4170
  * - [Mongoose `Aggregate`](/docs/api/aggregate.html)
4171
4171
  * - [An Introduction to Mongoose Aggregate](https://masteringjs.io/tutorials/mongoose/aggregate)
4172
- * - [MongoDB Aggregation docs](http://docs.mongodb.org/manual/applications/aggregation/)
4172
+ * - [MongoDB Aggregation docs](https://docs.mongodb.org/manual/applications/aggregation/)
4173
4173
  *
4174
4174
  * @see Aggregate #aggregate_Aggregate
4175
- * @see MongoDB http://docs.mongodb.org/manual/applications/aggregation/
4175
+ * @see MongoDB https://docs.mongodb.org/manual/applications/aggregation/
4176
4176
  * @param {Array} [pipeline] aggregation pipeline as an array of objects
4177
4177
  * @param {Object} [options] aggregation options
4178
4178
  * @param {Function} [callback]
@@ -4183,7 +4183,7 @@ Model.mapReduce = function mapReduce(o, callback) {
4183
4183
  Model.aggregate = function aggregate(pipeline, options, callback) {
4184
4184
  _checkContext(this, 'aggregate');
4185
4185
 
4186
- if (arguments.length > 3 || get(pipeline, 'constructor.name') === 'Object') {
4186
+ if (arguments.length > 3 || (pipeline && pipeline.constructor && pipeline.constructor.name) === 'Object') {
4187
4187
  throw new MongooseError('Mongoose 5.x disallows passing a spread of operators ' +
4188
4188
  'to `Model.aggregate()`. Instead of ' +
4189
4189
  '`Model.aggregate({ $match }, { $skip })`, do ' +
@@ -4391,6 +4391,7 @@ Model.validate = function validate(obj, pathsToValidate, context, callback) {
4391
4391
  * @param {Document|Array} docs Either a single document or array of documents to populate.
4392
4392
  * @param {Object|String} options Either the paths to populate or an object specifying all parameters
4393
4393
  * @param {string} [options.path=null] The path to populate.
4394
+ * @param {string|PopulateOptions} [options.populate=null] Recursively populate paths in the populated documents. See [deep populate docs](/docs/populate.html#deep-populate).
4394
4395
  * @param {boolean} [options.retainNullValues=false] By default, Mongoose removes null and undefined values from populated arrays. Use this option to make `populate()` retain `null` and `undefined` array entries.
4395
4396
  * @param {boolean} [options.getters=false] If true, Mongoose will call any getters defined on the `localField`. By default, Mongoose gets the raw value of `localField`. For example, you would need to set this option to `true` if you wanted to [add a `lowercase` getter to your `localField`](/docs/schematypes.html#schematype-options).
4396
4397
  * @param {boolean} [options.clone=false] When you do `BlogPost.find().populate('author')`, blog posts with the same author will share 1 copy of an `author` doc. Enable this option to make Mongoose clone populated docs before assigning them.
@@ -4506,7 +4507,10 @@ function populate(model, docs, options, callback) {
4506
4507
  ids = utils.array.unique(ids);
4507
4508
 
4508
4509
  const assignmentOpts = {};
4509
- assignmentOpts.sort = get(mod, 'options.options.sort', void 0);
4510
+ assignmentOpts.sort = mod &&
4511
+ mod.options &&
4512
+ mod.options.options &&
4513
+ mod.options.options.sort || void 0;
4510
4514
  assignmentOpts.excludeId = excludeIdReg.test(select) || (select && select._id === 0);
4511
4515
 
4512
4516
  if (ids.length === 0 || ids.every(utils.isNullOrUndefined)) {
@@ -4675,7 +4679,9 @@ function _assign(model, vals, mod, assignmentOpts) {
4675
4679
  const isVirtual = mod.isVirtual;
4676
4680
  const justOne = mod.justOne;
4677
4681
  let _val;
4678
- const lean = get(options, 'options.lean', false);
4682
+ const lean = options &&
4683
+ options.options &&
4684
+ options.options.lean || false;
4679
4685
  const len = vals.length;
4680
4686
  const rawOrder = {};
4681
4687
  const rawDocs = {};
@@ -4746,7 +4752,7 @@ function _assign(model, vals, mod, assignmentOpts) {
4746
4752
  }
4747
4753
  // flag each as result of population
4748
4754
  if (!lean) {
4749
- val.$__.wasPopulated = true;
4755
+ val.$__.wasPopulated = val.$__.wasPopulated || true;
4750
4756
  }
4751
4757
  }
4752
4758
  }