mongoose 6.2.9 → 6.3.0

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 (64) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/dist/browser.umd.js +2 -1693
  3. package/lib/aggregate.js +59 -67
  4. package/lib/browser.js +4 -4
  5. package/lib/connection.js +21 -21
  6. package/lib/cursor/AggregationCursor.js +2 -2
  7. package/lib/cursor/ChangeStream.js +42 -2
  8. package/lib/cursor/QueryCursor.js +5 -3
  9. package/lib/document.js +39 -46
  10. package/lib/error/eachAsyncMultiError.js +41 -0
  11. package/lib/error/index.js +2 -2
  12. package/lib/helpers/cursor/eachAsync.js +44 -12
  13. package/lib/helpers/indexes/applySchemaCollation.js +13 -0
  14. package/lib/helpers/indexes/isTextIndex.js +16 -0
  15. package/lib/helpers/model/discriminator.js +1 -3
  16. package/lib/helpers/populate/markArraySubdocsPopulated.js +1 -1
  17. package/lib/helpers/projection/hasIncludedChildren.js +1 -1
  18. package/lib/helpers/query/applyGlobalOption.js +29 -0
  19. package/lib/helpers/query/castUpdate.js +3 -1
  20. package/lib/helpers/update/applyTimestampsToChildren.js +2 -2
  21. package/lib/helpers/update/applyTimestampsToUpdate.js +0 -1
  22. package/lib/index.js +33 -26
  23. package/lib/model.js +88 -90
  24. package/lib/options/SchemaArrayOptions.js +2 -2
  25. package/lib/options/SchemaBufferOptions.js +1 -1
  26. package/lib/options/SchemaDateOptions.js +2 -2
  27. package/lib/options/SchemaDocumentArrayOptions.js +3 -3
  28. package/lib/options/SchemaMapOptions.js +2 -2
  29. package/lib/options/SchemaNumberOptions.js +3 -3
  30. package/lib/options/SchemaObjectIdOptions.js +2 -2
  31. package/lib/options/SchemaStringOptions.js +1 -1
  32. package/lib/options/SchemaSubdocumentOptions.js +2 -2
  33. package/lib/options/SchemaTypeOptions.js +3 -3
  34. package/lib/query.js +273 -249
  35. package/lib/schema/SubdocumentPath.js +4 -3
  36. package/lib/schema/array.js +2 -2
  37. package/lib/schema/boolean.js +4 -4
  38. package/lib/schema/buffer.js +3 -3
  39. package/lib/schema/date.js +7 -7
  40. package/lib/schema/decimal128.js +2 -2
  41. package/lib/schema/documentarray.js +3 -3
  42. package/lib/schema/mixed.js +2 -2
  43. package/lib/schema/number.js +6 -6
  44. package/lib/schema/objectid.js +4 -7
  45. package/lib/schema/string.js +38 -16
  46. package/lib/schema.js +144 -30
  47. package/lib/schematype.js +75 -68
  48. package/lib/types/ArraySubdocument.js +1 -1
  49. package/lib/types/DocumentArray/methods/index.js +2 -2
  50. package/lib/types/array/index.js +1 -1
  51. package/lib/types/array/methods/index.js +13 -13
  52. package/lib/types/buffer.js +1 -1
  53. package/lib/types/decimal128.js +1 -1
  54. package/lib/types/objectid.js +1 -1
  55. package/lib/types/subdocument.js +31 -2
  56. package/lib/validoptions.js +1 -0
  57. package/lib/virtualtype.js +3 -3
  58. package/package.json +19 -13
  59. package/tools/repl.js +2 -1
  60. package/types/aggregate.d.ts +223 -0
  61. package/types/cursor.d.ts +10 -4
  62. package/types/index.d.ts +194 -209
  63. package/types/mongooseoptions.d.ts +10 -4
  64. package/lib/helpers/query/applyGlobalMaxTimeMS.js +0 -15
package/lib/model.js CHANGED
@@ -26,6 +26,7 @@ const applyQueryMiddleware = require('./helpers/query/applyQueryMiddleware');
26
26
  const applyHooks = require('./helpers/model/applyHooks');
27
27
  const applyMethods = require('./helpers/model/applyMethods');
28
28
  const applyProjection = require('./helpers/projection/applyProjection');
29
+ const applySchemaCollation = require('./helpers/indexes/applySchemaCollation');
29
30
  const applyStaticHooks = require('./helpers/model/applyStaticHooks');
30
31
  const applyStatics = require('./helpers/model/applyStatics');
31
32
  const applyWriteConcern = require('./helpers/schema/applyWriteConcern');
@@ -82,7 +83,7 @@ const saveToObjectOptions = Object.assign({}, internalToObjectOptions, {
82
83
  * [`connection.model()`](./api.html#connection_Connection-model) functions
83
84
  * create subclasses of `mongoose.Model` as shown below.
84
85
  *
85
- * ####Example:
86
+ * #### Example:
86
87
  *
87
88
  * // `UserModel` is a "Model", a subclass of `mongoose.Model`.
88
89
  * const UserModel = mongoose.model('User', new Schema({ name: String }));
@@ -201,12 +202,12 @@ Model.prototype.baseModelName;
201
202
  * Event emitter that reports any errors that occurred. Useful for global error
202
203
  * handling.
203
204
  *
204
- * ####Example:
205
+ * #### Example:
205
206
  *
206
207
  * MyModel.events.on('error', err => console.log(err.message));
207
208
  *
208
209
  * // Prints a 'CastError' because of the above handler
209
- * await MyModel.findOne({ _id: 'notanid' }).catch(noop);
210
+ * await MyModel.findOne({ _id: 'Not a valid ObjectId' }).catch(noop);
210
211
  *
211
212
  * @api public
212
213
  * @fires error whenever any query or model function errors
@@ -343,7 +344,8 @@ Model.prototype.$__handleSave = function(options, callback) {
343
344
  } else {
344
345
  const optionsWithCustomValues = Object.assign({}, options, saveOptions);
345
346
  const where = this.$__where();
346
- if (this.$__schema.options.optimisticConcurrency) {
347
+ const optimisticConcurrency = this.$__schema.options.optimisticConcurrency;
348
+ if (optimisticConcurrency) {
347
349
  const key = this.$__schema.options.versionKey;
348
350
  const val = this.$__getValue(key);
349
351
  if (val != null) {
@@ -397,7 +399,7 @@ Model.prototype.$__save = function(options, callback) {
397
399
  }
398
400
  }
399
401
 
400
- const versionBump = this.$__.version || this.$__schema.options.optimisticConcurrency;
402
+ const versionBump = this.$__.version;
401
403
  // was this an update that required a version bump?
402
404
  if (versionBump && !this.$__.inserting) {
403
405
  const doIncrement = VERSION_INC === (VERSION_INC & this.$__.version);
@@ -452,7 +454,7 @@ function generateVersionError(doc, modifiedPaths) {
452
454
  * Saves this document by inserting a new document into the database if [document.isNew](/docs/api.html#document_Document-isNew) is `true`,
453
455
  * or sends an [updateOne](/docs/api.html#document_Document-updateOne) operation with just the modified paths if `isNew` is `false`.
454
456
  *
455
- * ####Example:
457
+ * #### Example:
456
458
  *
457
459
  * product.sold = Date.now();
458
460
  * product = await product.save();
@@ -460,7 +462,7 @@ function generateVersionError(doc, modifiedPaths) {
460
462
  * If save is successful, the returned promise will fulfill with the document
461
463
  * saved.
462
464
  *
463
- * ####Example:
465
+ * #### Example:
464
466
  *
465
467
  * const newProduct = await product.save();
466
468
  * newProduct === product; // true
@@ -575,7 +577,6 @@ function operand(self, where, delta, data, val, op) {
575
577
  if (VERSION_ALL === (VERSION_ALL & self.$__.version)) return;
576
578
 
577
579
  if (self.$__schema.options.optimisticConcurrency) {
578
- self.$__.version = VERSION_ALL;
579
580
  return;
580
581
  }
581
582
 
@@ -698,6 +699,12 @@ function handleAtomics(self, where, delta, data, value) {
698
699
 
699
700
  Model.prototype.$__delta = function() {
700
701
  const dirty = this.$__dirty();
702
+
703
+ const optimisticConcurrency = this.$__schema.options.optimisticConcurrency;
704
+ if (optimisticConcurrency) {
705
+ this.$__.version = dirty.length ? VERSION_ALL : VERSION_WHERE;
706
+ }
707
+
701
708
  if (!dirty.length && VERSION_ALL !== this.$__.version) {
702
709
  return;
703
710
  }
@@ -883,7 +890,7 @@ Model.prototype.$__version = function(where, delta) {
883
890
  /**
884
891
  * Signal that we desire an increment of this documents version.
885
892
  *
886
- * ####Example:
893
+ * #### Example:
887
894
  *
888
895
  * Model.findById(id, function (err, doc) {
889
896
  * doc.increment();
@@ -927,7 +934,7 @@ Model.prototype.$__where = function _where(where) {
927
934
  /**
928
935
  * Removes this document from the db.
929
936
  *
930
- * ####Example:
937
+ * #### Example:
931
938
  * product.remove(function (err, product) {
932
939
  * if (err) return handleError(err);
933
940
  * Product.findById(product._id, function (err, product) {
@@ -938,7 +945,7 @@ Model.prototype.$__where = function _where(where) {
938
945
  *
939
946
  * 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
940
947
  *
941
- * ####Example:
948
+ * #### Example:
942
949
  * product.remove().then(function (product) {
943
950
  * ...
944
951
  * }).catch(function (err) {
@@ -985,7 +992,7 @@ Model.prototype.delete = Model.prototype.remove;
985
992
  /**
986
993
  * Removes this document from the db. Equivalent to `.remove()`.
987
994
  *
988
- * ####Example:
995
+ * #### Example:
989
996
  * product = await product.deleteOne();
990
997
  * await Product.findById(product._id); // null
991
998
  *
@@ -1054,7 +1061,7 @@ Model.prototype.$__deleteOne = Model.prototype.$__remove;
1054
1061
  /**
1055
1062
  * Returns another Model instance.
1056
1063
  *
1057
- * ####Example:
1064
+ * #### Example:
1058
1065
  *
1059
1066
  * const doc = new Tank;
1060
1067
  * doc.model('User').findById(id, callback);
@@ -1074,7 +1081,7 @@ Model.prototype.model = function model(name) {
1074
1081
  * Under the hood, `MyModel.exists({ answer: 42 })` is equivalent to
1075
1082
  * `MyModel.findOne({ answer: 42 }).select({ _id: 1 }).lean()`
1076
1083
  *
1077
- * ####Example:
1084
+ * #### Example:
1078
1085
  * await Character.deleteMany({});
1079
1086
  * await Character.create({ name: 'Jean-Luc Picard' });
1080
1087
  *
@@ -1113,7 +1120,7 @@ Model.exists = function exists(filter, options, callback) {
1113
1120
  /**
1114
1121
  * Adds a discriminator type.
1115
1122
  *
1116
- * ####Example:
1123
+ * #### Example:
1117
1124
  *
1118
1125
  * function BaseSchema() {
1119
1126
  * Schema.apply(this, arguments);
@@ -1242,7 +1249,7 @@ for (const i in EventEmitter.prototype) {
1242
1249
  * to get back a promise that will resolve when your indexes are finished
1243
1250
  * building as an alternative to [`MyModel.on('index')`](/docs/guide.html#indexes)
1244
1251
  *
1245
- * ####Example:
1252
+ * #### Example:
1246
1253
  *
1247
1254
  * const eventSchema = new Schema({ thing: { type: 'string', unique: true }})
1248
1255
  * // This calls `Event.init()` implicitly, so you don't need to call
@@ -1328,7 +1335,7 @@ Model.init = function init(callback) {
1328
1335
  * Note 2: You don't have to call this if your schema contains index or unique field.
1329
1336
  * In that case, just use `Model.init()`
1330
1337
  *
1331
- * ####Example:
1338
+ * #### Example:
1332
1339
  *
1333
1340
  * const userSchema = new Schema({ name: String })
1334
1341
  * const User = mongoose.model('User', userSchema);
@@ -1410,7 +1417,7 @@ Model.createCollection = function createCollection(options, callback) {
1410
1417
  * See the [introductory blog post](https://thecodebarbarian.com/whats-new-in-mongoose-5-2-syncindexes)
1411
1418
  * for more information.
1412
1419
  *
1413
- * ####Example:
1420
+ * #### Example:
1414
1421
  *
1415
1422
  * const schema = new Schema({ name: { type: String, unique: true } });
1416
1423
  * const Customer = mongoose.model('Customer', schema);
@@ -1556,6 +1563,7 @@ Model.cleanIndexes = function cleanIndexes(callback) {
1556
1563
 
1557
1564
  for (const [schemaIndexKeysObject, schemaIndexOptions] of schemaIndexes) {
1558
1565
  const options = decorateDiscriminatorIndexOptions(this.schema, utils.clone(schemaIndexOptions));
1566
+ applySchemaCollation(schemaIndexKeysObject, options, this.schema.options);
1559
1567
 
1560
1568
  if (isIndexEqual(schemaIndexKeysObject, options, dbIndex)) {
1561
1569
  found = true;
@@ -1628,7 +1636,7 @@ Model.listIndexes = function init(callback) {
1628
1636
  * Sends `createIndex` commands to mongo for each index declared in the schema.
1629
1637
  * The `createIndex` commands are sent in series.
1630
1638
  *
1631
- * ####Example:
1639
+ * #### Example:
1632
1640
  *
1633
1641
  * Event.ensureIndexes(function (err) {
1634
1642
  * if (err) return handleError(err);
@@ -1636,7 +1644,7 @@ Model.listIndexes = function init(callback) {
1636
1644
  *
1637
1645
  * After completion, an `index` event is emitted on this `Model` passing an error if one occurred.
1638
1646
  *
1639
- * ####Example:
1647
+ * #### Example:
1640
1648
  *
1641
1649
  * const eventSchema = new Schema({ thing: { type: 'string', unique: true }})
1642
1650
  * const Event = mongoose.model('Event', eventSchema);
@@ -1774,26 +1782,17 @@ function _ensureIndexes(model, options, callback) {
1774
1782
 
1775
1783
  const indexFields = utils.clone(index[0]);
1776
1784
  const indexOptions = utils.clone(index[1]);
1777
- let isTextIndex = false;
1778
- for (const key of Object.keys(indexFields)) {
1779
- if (indexFields[key] === 'text') {
1780
- isTextIndex = true;
1781
- }
1782
- }
1785
+
1783
1786
  delete indexOptions._autoIndex;
1784
1787
  decorateDiscriminatorIndexOptions(model.schema, indexOptions);
1785
1788
  applyWriteConcern(model.schema, indexOptions);
1789
+ applySchemaCollation(indexFields, indexOptions, model.schema.options);
1786
1790
 
1787
1791
  indexSingleStart(indexFields, options);
1788
1792
 
1789
1793
  if ('background' in options) {
1790
1794
  indexOptions.background = options.background;
1791
1795
  }
1792
- if (model.schema.options.hasOwnProperty('collation') &&
1793
- !indexOptions.hasOwnProperty('collation') &&
1794
- !isTextIndex) {
1795
- indexOptions.collation = model.schema.options.collation;
1796
- }
1797
1796
 
1798
1797
  model.collection.createIndex(indexFields, indexOptions, utils.tick(function(err, name) {
1799
1798
  indexSingleDone(err, indexFields, indexOptions, name);
@@ -1873,7 +1872,7 @@ Model.discriminators;
1873
1872
  /**
1874
1873
  * Translate any aliases fields/conditions so the final query or document object is pure
1875
1874
  *
1876
- * ####Example:
1875
+ * #### Example:
1877
1876
  *
1878
1877
  * Character
1879
1878
  * .find(Character.translateAliases({
@@ -1881,7 +1880,7 @@ Model.discriminators;
1881
1880
  * })
1882
1881
  * .exec(function(err, characters) {})
1883
1882
  *
1884
- * ####Note:
1883
+ * #### Note:
1885
1884
  * Only translate arguments of object type anything else is returned raw
1886
1885
  *
1887
1886
  * @param {Object} fields fields/conditions that may contain aliased keys
@@ -1970,12 +1969,12 @@ Model.translateAliases = function translateAliases(fields) {
1970
1969
  *
1971
1970
  * This method is deprecated. See [Deprecation Warnings](../deprecations.html#remove) for details.
1972
1971
  *
1973
- * ####Example:
1972
+ * #### Example:
1974
1973
  *
1975
1974
  * const res = await Character.remove({ name: 'Eddard Stark' });
1976
1975
  * res.deletedCount; // Number of documents removed
1977
1976
  *
1978
- * ####Note:
1977
+ * #### Note:
1979
1978
  *
1980
1979
  * This method sends a remove command directly to MongoDB, no Mongoose documents
1981
1980
  * are involved. Because no Mongoose documents are involved, Mongoose does
@@ -2017,11 +2016,11 @@ Model.remove = function remove(conditions, options, callback) {
2017
2016
  * Behaves like `remove()`, but deletes at most one document regardless of the
2018
2017
  * `single` option.
2019
2018
  *
2020
- * ####Example:
2019
+ * #### Example:
2021
2020
  *
2022
2021
  * await Character.deleteOne({ name: 'Eddard Stark' }); // returns {deletedCount: 1}
2023
2022
  *
2024
- * ####Note:
2023
+ * #### Note:
2025
2024
  *
2026
2025
  * This function triggers `deleteOne` query hooks. Read the
2027
2026
  * [middleware docs](/docs/middleware.html#naming) to learn more.
@@ -2060,11 +2059,11 @@ Model.deleteOne = function deleteOne(conditions, options, callback) {
2060
2059
  * Behaves like `remove()`, but deletes all documents that match `conditions`
2061
2060
  * regardless of the `single` option.
2062
2061
  *
2063
- * ####Example:
2062
+ * #### Example:
2064
2063
  *
2065
2064
  * await Character.deleteMany({ name: /Stark/, age: { $gte: 18 } }); // returns {deletedCount: x} where x is the number of documents deleted.
2066
2065
  *
2067
- * ####Note:
2066
+ * #### Note:
2068
2067
  *
2069
2068
  * This function triggers `deleteMany` query hooks. Read the
2070
2069
  * [middleware docs](/docs/middleware.html#naming) to learn more.
@@ -2103,7 +2102,7 @@ Model.deleteMany = function deleteMany(conditions, options, callback) {
2103
2102
  * See our [query casting tutorial](/docs/tutorials/query_casting.html) for
2104
2103
  * more information on how Mongoose casts `filter`.
2105
2104
  *
2106
- * ####Examples:
2105
+ * #### Examples:
2107
2106
  *
2108
2107
  * // find all documents
2109
2108
  * await MyModel.find({});
@@ -2179,7 +2178,7 @@ Model.find = function find(conditions, projection, options, callback) {
2179
2178
  * to `findOne({})` and return arbitrary documents. However, mongoose
2180
2179
  * translates `findById(undefined)` into `findOne({ _id: null })`.
2181
2180
  *
2182
- * ####Example:
2181
+ * #### Example:
2183
2182
  *
2184
2183
  * // Find the adventure with the given `id`, or `null` if not found
2185
2184
  * await Adventure.findById(id).exec();
@@ -2222,7 +2221,7 @@ Model.findById = function findById(id, projection, options, callback) {
2222
2221
  * mongoose will send an empty `findOne` command to MongoDB, which will return
2223
2222
  * an arbitrary document. If you're querying by `_id`, use `findById()` instead.
2224
2223
  *
2225
- * ####Example:
2224
+ * #### Example:
2226
2225
  *
2227
2226
  * // Find one adventure whose `country` is 'Croatia', otherwise `null`
2228
2227
  * await Adventure.findOne({ country: 'Croatia' }).exec();
@@ -2278,7 +2277,7 @@ Model.findOne = function findOne(conditions, projection, options, callback) {
2278
2277
  * `estimatedDocumentCount()` uses collection metadata rather than scanning
2279
2278
  * the entire collection.
2280
2279
  *
2281
- * ####Example:
2280
+ * #### Example:
2282
2281
  *
2283
2282
  * const numAdventures = await Adventure.estimatedDocumentCount();
2284
2283
  *
@@ -2301,7 +2300,7 @@ Model.estimatedDocumentCount = function estimatedDocumentCount(options, callback
2301
2300
  /**
2302
2301
  * Counts number of documents matching `filter` in a database collection.
2303
2302
  *
2304
- * ####Example:
2303
+ * #### Example:
2305
2304
  *
2306
2305
  * Adventure.countDocuments({ type: 'jungle' }, function (err, count) {
2307
2306
  * console.log('there are %d jungle adventures', count);
@@ -2356,7 +2355,7 @@ Model.countDocuments = function countDocuments(conditions, options, callback) {
2356
2355
  * a collection, e.g. `count({})`, use the [`estimatedDocumentCount()` function](/docs/api.html#model_Model.estimatedDocumentCount)
2357
2356
  * instead. Otherwise, use the [`countDocuments()`](/docs/api.html#model_Model.countDocuments) function instead.
2358
2357
  *
2359
- * ####Example:
2358
+ * #### Example:
2360
2359
  *
2361
2360
  * const count = await Adventure.count({ type: 'jungle' });
2362
2361
  * console.log('there are %d jungle adventures', count);
@@ -2388,7 +2387,7 @@ Model.count = function count(conditions, callback) {
2388
2387
  *
2389
2388
  * Passing a `callback` executes the query.
2390
2389
  *
2391
- * ####Example
2390
+ * #### Example
2392
2391
  *
2393
2392
  * Link.distinct('url', { clicks: {$gt: 100}}, function (err, result) {
2394
2393
  * if (err) return handleError(err);
@@ -2480,7 +2479,7 @@ Model.$where = function $where() {
2480
2479
  *
2481
2480
  * 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.
2482
2481
  *
2483
- * ####Options:
2482
+ * #### Options:
2484
2483
  *
2485
2484
  * - `new`: bool - if true, return the modified document rather than the original. defaults to false (changed in 4.0)
2486
2485
  * - `upsert`: bool - creates the object if it doesn't exist. defaults to false.
@@ -2493,7 +2492,7 @@ Model.$where = function $where() {
2493
2492
  * - `rawResult`: if true, returns the [raw result from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/4.3/interfaces/ModifyResult.html)
2494
2493
  * - `strict`: overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict) for this update
2495
2494
  *
2496
- * ####Examples:
2495
+ * #### Examples:
2497
2496
  *
2498
2497
  * A.findOneAndUpdate(conditions, update, options, callback) // executes
2499
2498
  * A.findOneAndUpdate(conditions, update, options) // returns Query
@@ -2501,11 +2500,11 @@ Model.$where = function $where() {
2501
2500
  * A.findOneAndUpdate(conditions, update) // returns Query
2502
2501
  * A.findOneAndUpdate() // returns Query
2503
2502
  *
2504
- * ####Note:
2503
+ * #### Note:
2505
2504
  *
2506
2505
  * All top level update keys which are not `atomic` operation names are treated as set operations:
2507
2506
  *
2508
- * ####Example:
2507
+ * #### Example:
2509
2508
  *
2510
2509
  * const query = { name: 'borne' };
2511
2510
  * Model.findOneAndUpdate(query, { name: 'jason bourne' }, options, callback)
@@ -2515,7 +2514,7 @@ Model.$where = function $where() {
2515
2514
  *
2516
2515
  * This helps prevent accidentally overwriting your document with `{ name: 'jason bourne' }`.
2517
2516
  *
2518
- * ####Note:
2517
+ * #### Note:
2519
2518
  *
2520
2519
  * `findOneAndX` and `findByIdAndX` functions support limited validation that
2521
2520
  * you can enable by setting the `runValidators` option.
@@ -2618,7 +2617,7 @@ function _decorateUpdateWithVersionKey(update, options, versionKey) {
2618
2617
  *
2619
2618
  * - `findOneAndUpdate()`
2620
2619
  *
2621
- * ####Options:
2620
+ * #### Options:
2622
2621
  *
2623
2622
  * - `new`: bool - true to return the modified document rather than the original. defaults to false
2624
2623
  * - `upsert`: bool - creates the object if it doesn't exist. defaults to false.
@@ -2629,7 +2628,7 @@ function _decorateUpdateWithVersionKey(update, options, versionKey) {
2629
2628
  * - `rawResult`: if true, returns the [raw result from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/4.3/interfaces/ModifyResult.html)
2630
2629
  * - `strict`: overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict) for this update
2631
2630
  *
2632
- * ####Examples:
2631
+ * #### Examples:
2633
2632
  *
2634
2633
  * A.findByIdAndUpdate(id, update, options, callback) // executes
2635
2634
  * A.findByIdAndUpdate(id, update, options) // returns Query
@@ -2637,11 +2636,11 @@ function _decorateUpdateWithVersionKey(update, options, versionKey) {
2637
2636
  * A.findByIdAndUpdate(id, update) // returns Query
2638
2637
  * A.findByIdAndUpdate() // returns Query
2639
2638
  *
2640
- * ####Note:
2639
+ * #### Note:
2641
2640
  *
2642
2641
  * All top level update keys which are not `atomic` operation names are treated as set operations:
2643
2642
  *
2644
- * ####Example:
2643
+ * #### Example:
2645
2644
  *
2646
2645
  * Model.findByIdAndUpdate(id, { name: 'jason bourne' }, options, callback)
2647
2646
  *
@@ -2650,7 +2649,7 @@ function _decorateUpdateWithVersionKey(update, options, versionKey) {
2650
2649
  *
2651
2650
  * This helps prevent accidentally overwriting your document with `{ name: 'jason bourne' }`.
2652
2651
  *
2653
- * ####Note:
2652
+ * #### Note:
2654
2653
  *
2655
2654
  * `findOneAndX` and `findByIdAndX` functions support limited validation. You can
2656
2655
  * enable validation by setting the `runValidators` option.
@@ -2721,7 +2720,7 @@ Model.findByIdAndUpdate = function(id, update, options, callback) {
2721
2720
  * this distinction is purely pedantic. You should use `findOneAndDelete()`
2722
2721
  * unless you have a good reason not to.
2723
2722
  *
2724
- * ####Options:
2723
+ * #### Options:
2725
2724
  *
2726
2725
  * - `sort`: if multiple docs are found by the conditions, sets the sort order to choose which doc to update
2727
2726
  * - `maxTimeMS`: puts a time limit on the query - requires mongodb >= 2.6.0
@@ -2730,7 +2729,7 @@ Model.findByIdAndUpdate = function(id, update, options, callback) {
2730
2729
  * - `rawResult`: if true, returns the [raw result from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/4.3/interfaces/ModifyResult.html)
2731
2730
  * - `strict`: overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict) for this update
2732
2731
  *
2733
- * ####Examples:
2732
+ * #### Examples:
2734
2733
  *
2735
2734
  * A.findOneAndDelete(conditions, options, callback) // executes
2736
2735
  * A.findOneAndDelete(conditions, options) // return Query
@@ -2834,7 +2833,7 @@ Model.findByIdAndDelete = function(id, options, callback) {
2834
2833
  *
2835
2834
  * - `findOneAndReplace()`
2836
2835
  *
2837
- * ####Options:
2836
+ * #### Options:
2838
2837
  *
2839
2838
  * - `sort`: if multiple docs are found by the conditions, sets the sort order to choose which doc to update
2840
2839
  * - `maxTimeMS`: puts a time limit on the query - requires mongodb >= 2.6.0
@@ -2843,7 +2842,7 @@ Model.findByIdAndDelete = function(id, options, callback) {
2843
2842
  * - `rawResult`: if true, returns the [raw result from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/4.3/interfaces/ModifyResult.html)
2844
2843
  * - `strict`: overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict) for this update
2845
2844
  *
2846
- * ####Examples:
2845
+ * #### Examples:
2847
2846
  *
2848
2847
  * A.findOneAndReplace(filter, replacement, options, callback) // executes
2849
2848
  * A.findOneAndReplace(filter, replacement, options) // return Query
@@ -2913,7 +2912,7 @@ Model.findOneAndReplace = function(filter, replacement, options, callback) {
2913
2912
  *
2914
2913
  * - `findOneAndRemove()`
2915
2914
  *
2916
- * ####Options:
2915
+ * #### Options:
2917
2916
  *
2918
2917
  * - `sort`: if multiple docs are found by the conditions, sets the sort order to choose which doc to update
2919
2918
  * - `maxTimeMS`: puts a time limit on the query - requires mongodb >= 2.6.0
@@ -2922,7 +2921,7 @@ Model.findOneAndReplace = function(filter, replacement, options, callback) {
2922
2921
  * - `rawResult`: if true, returns the [raw result from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/4.3/interfaces/ModifyResult.html)
2923
2922
  * - `strict`: overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict) for this update
2924
2923
  *
2925
- * ####Examples:
2924
+ * #### Examples:
2926
2925
  *
2927
2926
  * A.findOneAndRemove(conditions, options, callback) // executes
2928
2927
  * A.findOneAndRemove(conditions, options) // return Query
@@ -2993,14 +2992,14 @@ Model.findOneAndRemove = function(conditions, options, callback) {
2993
2992
  *
2994
2993
  * - `findOneAndRemove()`
2995
2994
  *
2996
- * ####Options:
2995
+ * #### Options:
2997
2996
  *
2998
2997
  * - `sort`: if multiple docs are found by the conditions, sets the sort order to choose which doc to update
2999
2998
  * - `select`: sets the document fields to return
3000
2999
  * - `rawResult`: if true, returns the [raw result from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/4.3/interfaces/ModifyResult.html)
3001
3000
  * - `strict`: overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict) for this update
3002
3001
  *
3003
- * ####Examples:
3002
+ * #### Examples:
3004
3003
  *
3005
3004
  * A.findByIdAndRemove(id, options, callback) // executes
3006
3005
  * A.findByIdAndRemove(id, options) // return Query
@@ -3043,7 +3042,7 @@ Model.findByIdAndRemove = function(id, options, callback) {
3043
3042
  *
3044
3043
  * - `save()`
3045
3044
  *
3046
- * ####Example:
3045
+ * #### Example:
3047
3046
  *
3048
3047
  * // Insert one new `Character` document
3049
3048
  * await Character.create({ name: 'Jean-Luc Picard' });
@@ -3195,7 +3194,7 @@ Model.create = function create(doc, options, callback) {
3195
3194
  * - 'end': Emitted if the underlying stream is closed
3196
3195
  * - 'close': Emitted if the underlying stream is closed
3197
3196
  *
3198
- * ####Example:
3197
+ * #### Example:
3199
3198
  *
3200
3199
  * const doc = await Person.create({ name: 'Ned Stark' });
3201
3200
  * const changeStream = Person.watch().on('change', change => console.log(change));
@@ -3244,7 +3243,7 @@ Model.watch = function(pipeline, options) {
3244
3243
  *
3245
3244
  * This function does not trigger any middleware.
3246
3245
  *
3247
- * ####Example:
3246
+ * #### Example:
3248
3247
  *
3249
3248
  * const session = await Person.startSession();
3250
3249
  * let doc = await Person.findOne({ name: 'Ned Stark' }, null, { session });
@@ -3285,7 +3284,7 @@ Model.startSession = function() {
3285
3284
  *
3286
3285
  * - `insertMany()`
3287
3286
  *
3288
- * ####Example:
3287
+ * #### Example:
3289
3288
  *
3290
3289
  * const arr = [{ name: 'Star Wars' }, { name: 'The Empire Strikes Back' }];
3291
3290
  * Movies.insertMany(arr, function(error, docs) {});
@@ -3505,7 +3504,7 @@ function _setIsNew(doc, val) {
3505
3504
  * If you need to trigger
3506
3505
  * `save()` middleware for every document use [`create()`](https://mongoosejs.com/docs/api.html#model_Model.create) instead.
3507
3506
  *
3508
- * ####Example:
3507
+ * #### Example:
3509
3508
  *
3510
3509
  * Character.bulkWrite([
3511
3510
  * {
@@ -3761,7 +3760,7 @@ Model.buildBulkWriteOperations = function buildBulkWriteOperations(documents, op
3761
3760
  * Shortcut for creating a new Document from existing raw data, pre-saved in the DB.
3762
3761
  * The document returned has no paths marked as modified initially.
3763
3762
  *
3764
- * ####Example:
3763
+ * #### Example:
3765
3764
  *
3766
3765
  * // hydrate previous data into a Mongoose document
3767
3766
  * const mongooseCandy = Candy.hydrate({ _id: '54108337212ffb6d459f854c', type: 'jelly bean' });
@@ -3796,7 +3795,7 @@ Model.hydrate = function(obj, projection) {
3796
3795
  *
3797
3796
  * This method is deprecated. See [Deprecation Warnings](../deprecations.html#update) for details.
3798
3797
  *
3799
- * ####Examples:
3798
+ * #### Examples:
3800
3799
  *
3801
3800
  * MyModel.update({ age: { $gt: 18 } }, { oldEnough: true }, fn);
3802
3801
  *
@@ -3806,7 +3805,7 @@ Model.hydrate = function(obj, projection) {
3806
3805
  * // had `ferret` set to `true`, `nModified` will be 0.
3807
3806
  * res.nModified;
3808
3807
  *
3809
- * ####Valid options:
3808
+ * #### Valid options:
3810
3809
  *
3811
3810
  * - `strict` (boolean): overrides the [schema-level `strict` option](/docs/guide.html#strict) for this update
3812
3811
  * - `upsert` (boolean): whether to create the doc if it doesn't match (false)
@@ -3824,11 +3823,11 @@ Model.hydrate = function(obj, projection) {
3824
3823
  * - `err` is the error if any occurred
3825
3824
  * - `rawResponse` is the full response from Mongo
3826
3825
  *
3827
- * ####Note:
3826
+ * #### Note:
3828
3827
  *
3829
3828
  * All top level keys which are not `atomic` operation names are treated as set operations:
3830
3829
  *
3831
- * ####Example:
3830
+ * #### Example:
3832
3831
  *
3833
3832
  * const query = { name: 'borne' };
3834
3833
  * Model.update(query, { name: 'jason bourne' }, options, callback);
@@ -3839,7 +3838,7 @@ Model.hydrate = function(obj, projection) {
3839
3838
  *
3840
3839
  * This helps prevent accidentally overwriting all documents in your collection with `{ name: 'jason bourne' }`.
3841
3840
  *
3842
- * ####Note:
3841
+ * #### Note:
3843
3842
  *
3844
3843
  * 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.
3845
3844
  *
@@ -3880,7 +3879,7 @@ Model.update = function update(conditions, doc, options, callback) {
3880
3879
  * **Note** updateMany will _not_ fire update middleware. Use `pre('updateMany')`
3881
3880
  * and `post('updateMany')` instead.
3882
3881
  *
3883
- * ####Example:
3882
+ * #### Example:
3884
3883
  * const res = await Person.updateMany({ name: /Stark$/ }, { isDeleted: true });
3885
3884
  * res.matchedCount; // Number of documents matched
3886
3885
  * res.modifiedCount; // Number of documents modified
@@ -3920,7 +3919,7 @@ Model.updateMany = function updateMany(conditions, doc, options, callback) {
3920
3919
  * - MongoDB will update _only_ the first document that matches `filter` regardless of the value of the `multi` option.
3921
3920
  * - Use `replaceOne()` if you want to overwrite an entire document rather than using atomic operators like `$set`.
3922
3921
  *
3923
- * ####Example:
3922
+ * #### Example:
3924
3923
  * const res = await Person.updateOne({ name: 'Jean-Luc Picard' }, { ship: 'USS Enterprise' });
3925
3924
  * res.matchedCount; // Number of documents matched
3926
3925
  * res.modifiedCount; // Number of documents modified
@@ -3957,7 +3956,7 @@ Model.updateOne = function updateOne(conditions, doc, options, callback) {
3957
3956
  * Same as `update()`, except MongoDB replace the existing document with the
3958
3957
  * given document (no atomic operators like `$set`).
3959
3958
  *
3960
- * ####Example:
3959
+ * #### Example:
3961
3960
  * const res = await Person.replaceOne({ _id: 24601 }, { name: 'Jean Valjean' });
3962
3961
  * res.matchedCount; // Number of documents matched
3963
3962
  * res.modifiedCount; // Number of documents modified
@@ -4028,7 +4027,7 @@ function _update(model, op, conditions, doc, options, callback) {
4028
4027
  *
4029
4028
  * This function does not trigger any middleware.
4030
4029
  *
4031
- * ####Example:
4030
+ * #### Example:
4032
4031
  *
4033
4032
  * const o = {};
4034
4033
  * // `map()` and `reduce()` are run on the MongoDB server, not Node.js,
@@ -4039,7 +4038,7 @@ function _update(model, op, conditions, doc, options, callback) {
4039
4038
  * console.log(results)
4040
4039
  * })
4041
4040
  *
4042
- * ####Other options:
4041
+ * #### Other options:
4043
4042
  *
4044
4043
  * - `query` {Object} query filter object.
4045
4044
  * - `sort` {Object} sort input objects using this key
@@ -4052,7 +4051,7 @@ function _update(model, op, conditions, doc, options, callback) {
4052
4051
  * - `readPreference` {String}
4053
4052
  * - `out*` {Object, default: {inline:1}} sets the output target for the map reduce job.
4054
4053
  *
4055
- * ####* out options:
4054
+ * #### * out options:
4056
4055
  *
4057
4056
  * - `{inline:1}` the results are returned in an array
4058
4057
  * - `{replace: 'collectionName'}` add the results to collectionName: the results replace the collection
@@ -4061,7 +4060,7 @@ function _update(model, op, conditions, doc, options, callback) {
4061
4060
  *
4062
4061
  * 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).
4063
4062
  *
4064
- * ####Example:
4063
+ * #### Example:
4065
4064
  *
4066
4065
  * const o = {};
4067
4066
  * // You can also define `map()` and `reduce()` as strings if your
@@ -4154,7 +4153,7 @@ Model.mapReduce = function mapReduce(o, callback) {
4154
4153
  *
4155
4154
  * - `aggregate()`
4156
4155
  *
4157
- * ####Example:
4156
+ * #### Example:
4158
4157
  *
4159
4158
  * // Find the max balance of all accounts
4160
4159
  * const res = await Users.aggregate([
@@ -4171,7 +4170,7 @@ Model.mapReduce = function mapReduce(o, callback) {
4171
4170
  * exec();
4172
4171
  * console.log(res); // [ { maxBalance: 98 } ]
4173
4172
  *
4174
- * ####NOTE:
4173
+ * #### Note:
4175
4174
  *
4176
4175
  * - Mongoose does **not** cast aggregation pipelines to the model's schema because `$project` and `$group` operators allow redefining the "shape" of the documents at any stage of the pipeline, which may leave documents in an incompatible format. You can use the [mongoose-cast-aggregation plugin](https://github.com/AbdelrahmanHafez/mongoose-cast-aggregation) to enable minimal casting for aggregation pipelines.
4177
4176
  * - The documents returned are plain javascript objects, not mongoose documents (since any shape of document can be returned).
@@ -4213,7 +4212,6 @@ Model.aggregate = function aggregate(pipeline, options, callback) {
4213
4212
 
4214
4213
  const aggregate = new Aggregate(pipeline || []);
4215
4214
  aggregate.model(this);
4216
-
4217
4215
  if (options != null) {
4218
4216
  aggregate.option(options);
4219
4217
  }
@@ -4233,7 +4231,7 @@ Model.aggregate = function aggregate(pipeline, options, callback) {
4233
4231
  * Casts and validates the given object against this model's schema, passing the
4234
4232
  * given `context` to custom validators.
4235
4233
  *
4236
- * ####Example:
4234
+ * #### Example:
4237
4235
  *
4238
4236
  * const Model = mongoose.model('Test', Schema({
4239
4237
  * name: { type: String, required: true },
@@ -4367,7 +4365,7 @@ Model.validate = function validate(obj, pathsToValidate, context, callback) {
4367
4365
  * Changed in Mongoose 6: the model you call `populate()` on should be the
4368
4366
  * "local field" model, **not** the "foreign field" model.
4369
4367
  *
4370
- * ####Available top-level options:
4368
+ * #### Available top-level options:
4371
4369
  *
4372
4370
  * - path: space delimited path(s) to populate
4373
4371
  * - select: optional fields to select
@@ -4377,7 +4375,7 @@ Model.validate = function validate(obj, pathsToValidate, context, callback) {
4377
4375
  * - justOne: optional boolean, if true Mongoose will always set `path` to an array. Inferred from schema by default.
4378
4376
  * - strictPopulate: optional boolean, set to `false` to allow populating paths that aren't in the schema.
4379
4377
  *
4380
- * ####Examples:
4378
+ * #### Examples:
4381
4379
  *
4382
4380
  * const Dog = mongoose.model('Dog', new Schema({ name: String, breed: String }));
4383
4381
  * const Person = mongoose.model('Person', new Schema({
@@ -4810,7 +4808,6 @@ Model.compile = function compile(name, schema, collectionName, connection, base)
4810
4808
  o[schema.options.versionKey] = Number;
4811
4809
  schema.add(o);
4812
4810
  }
4813
-
4814
4811
  let model;
4815
4812
  if (typeof name === 'function' && name.prototype instanceof Model) {
4816
4813
  model = name;
@@ -4854,6 +4851,7 @@ Model.compile = function compile(name, schema, collectionName, connection, base)
4854
4851
  model.model = function model(name) {
4855
4852
  return this.db.model(name);
4856
4853
  };
4854
+
4857
4855
  model.db = connection;
4858
4856
  model.prototype.db = connection;
4859
4857
  model.prototype[modelDbSymbol] = connection;
@@ -5027,7 +5025,7 @@ Model.$wrapCallback = function(callback) {
5027
5025
  * Helper for console.log. Given a model named 'MyModel', returns the string
5028
5026
  * `'Model { MyModel }'`.
5029
5027
  *
5030
- * ####Example:
5028
+ * #### Example:
5031
5029
  *
5032
5030
  * const MyModel = mongoose.model('Test', Schema({ name: String }));
5033
5031
  * MyModel.inspect(); // 'Model { Test }'