mongoose 5.5.0 → 5.5.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.
- package/History.md +43 -1
- package/lib/aggregate.js +16 -4
- package/lib/connection.js +7 -1
- package/lib/document.js +43 -36
- package/lib/drivers/node-mongodb-native/collection.js +16 -4
- package/lib/drivers/node-mongodb-native/index.js +1 -1
- package/lib/helpers/document/cleanModifiedSubpaths.js +3 -0
- package/lib/helpers/document/getEmbeddedDiscriminatorPath.js +5 -5
- package/lib/helpers/model/applyStaticHooks.js +3 -0
- package/lib/helpers/query/castUpdate.js +0 -2
- package/lib/helpers/schema/setParentPointers.js +5 -5
- package/lib/helpers/symbols.js +8 -11
- package/lib/helpers/update/applyTimestampsToChildren.js +22 -16
- package/lib/internal.js +1 -0
- package/lib/model.js +78 -24
- package/lib/query.js +76 -31
- package/lib/schema/array.js +50 -0
- package/lib/schema/documentarray.js +42 -26
- package/lib/schema.js +6 -5
- package/lib/schematype.js +32 -2
- package/lib/types/array.js +48 -24
- package/lib/types/documentarray.js +16 -13
- package/lib/types/embedded.js +1 -1
- package/lib/types/map.js +5 -0
- package/lib/types/subdocument.js +18 -1
- package/package.json +2 -2
package/lib/model.js
CHANGED
|
@@ -1120,14 +1120,6 @@ Model.init = function init(callback) {
|
|
|
1120
1120
|
return this.$init;
|
|
1121
1121
|
}
|
|
1122
1122
|
|
|
1123
|
-
// If `dropDatabase()` is called, this model's collection will not be
|
|
1124
|
-
// init-ed. It is sufficiently common to call `dropDatabase()` after
|
|
1125
|
-
// `mongoose.connect()` but before creating models that we want to
|
|
1126
|
-
// support this. See gh-6967
|
|
1127
|
-
this.db.$internalEmitter.once('dropDatabase', () => {
|
|
1128
|
-
delete this.$init;
|
|
1129
|
-
});
|
|
1130
|
-
|
|
1131
1123
|
const Promise = PromiseProvider.get();
|
|
1132
1124
|
const autoIndex = this.schema.options.autoIndex == null ?
|
|
1133
1125
|
this.db.config.autoIndex :
|
|
@@ -2611,7 +2603,8 @@ Model.findByIdAndDelete = function(id, options, callback) {
|
|
|
2611
2603
|
*
|
|
2612
2604
|
* - defaults. Use the `setDefaultsOnInsert` option to override.
|
|
2613
2605
|
*
|
|
2614
|
-
* @param {Object}
|
|
2606
|
+
* @param {Object} filter Replace the first document that matches this filter
|
|
2607
|
+
* @param {Object} [replacement] Replace with this document
|
|
2615
2608
|
* @param {Object} [options] optional see [`Query.prototype.setOptions()`](http://mongoosejs.com/docs/api.html#query_Query-setOptions)
|
|
2616
2609
|
* @param {Object} [options.lean] if truthy, mongoose will return the document as a plain JavaScript object rather than a mongoose document. See [`Query.lean()`](http://mongoosejs.com/docs/api.html#query_Query-lean).
|
|
2617
2610
|
* @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](http://mongoosejs.com/docs/guide.html#strict)
|
|
@@ -2621,18 +2614,24 @@ Model.findByIdAndDelete = function(id, options, callback) {
|
|
|
2621
2614
|
* @api public
|
|
2622
2615
|
*/
|
|
2623
2616
|
|
|
2624
|
-
Model.findOneAndReplace = function(
|
|
2625
|
-
if (arguments.length === 1 && typeof
|
|
2626
|
-
const msg = 'Model.
|
|
2627
|
-
+ ' ' + this.modelName + '.
|
|
2628
|
-
+ ' ' + this.modelName + '.
|
|
2629
|
-
+ ' ' + this.modelName + '.
|
|
2617
|
+
Model.findOneAndReplace = function(filter, replacement, options, callback) {
|
|
2618
|
+
if (arguments.length === 1 && typeof filter === 'function') {
|
|
2619
|
+
const msg = 'Model.findOneAndReplace(): First argument must not be a function.\n\n'
|
|
2620
|
+
+ ' ' + this.modelName + '.findOneAndReplace(conditions, callback)\n'
|
|
2621
|
+
+ ' ' + this.modelName + '.findOneAndReplace(conditions)\n'
|
|
2622
|
+
+ ' ' + this.modelName + '.findOneAndReplace()\n';
|
|
2630
2623
|
throw new TypeError(msg);
|
|
2631
2624
|
}
|
|
2632
2625
|
|
|
2633
|
-
if (typeof options === 'function') {
|
|
2626
|
+
if (arguments.length === 3 && typeof options === 'function') {
|
|
2634
2627
|
callback = options;
|
|
2635
|
-
options =
|
|
2628
|
+
options = replacement;
|
|
2629
|
+
replacement = void 0;
|
|
2630
|
+
}
|
|
2631
|
+
if (arguments.length === 2 && typeof replacement === 'function') {
|
|
2632
|
+
callback = replacement;
|
|
2633
|
+
replacement = void 0;
|
|
2634
|
+
options = void 0;
|
|
2636
2635
|
}
|
|
2637
2636
|
if (callback) {
|
|
2638
2637
|
callback = this.$wrapCallback(callback);
|
|
@@ -2647,7 +2646,7 @@ Model.findOneAndReplace = function(conditions, options, callback) {
|
|
|
2647
2646
|
const mq = new this.Query({}, {}, this, this.collection);
|
|
2648
2647
|
mq.select(fields);
|
|
2649
2648
|
|
|
2650
|
-
return mq.findOneAndReplace(
|
|
2649
|
+
return mq.findOneAndReplace(filter, replacement, options, callback);
|
|
2651
2650
|
};
|
|
2652
2651
|
|
|
2653
2652
|
/**
|
|
@@ -2897,6 +2896,11 @@ Model.create = function create(doc, options, callback) {
|
|
|
2897
2896
|
}
|
|
2898
2897
|
}
|
|
2899
2898
|
|
|
2899
|
+
// Make sure session is available in middleware
|
|
2900
|
+
if (options.session != null) {
|
|
2901
|
+
toSave.$session(options.session);
|
|
2902
|
+
}
|
|
2903
|
+
|
|
2900
2904
|
toSave.save(options, callbackWrapper);
|
|
2901
2905
|
});
|
|
2902
2906
|
});
|
|
@@ -3171,7 +3175,32 @@ Model.$__insertMany = function(arr, options, callback) {
|
|
|
3171
3175
|
* console.log(res.insertedCount, res.modifiedCount, res.deletedCount);
|
|
3172
3176
|
* });
|
|
3173
3177
|
*
|
|
3178
|
+
* The [supported operations](https://docs.mongodb.com/manual/reference/method/db.collection.bulkWrite/#db.collection.bulkWrite) are:
|
|
3179
|
+
*
|
|
3180
|
+
* - `insertOne`
|
|
3181
|
+
* - `updateOne`
|
|
3182
|
+
* - `updateMany`
|
|
3183
|
+
* - `deleteOne`
|
|
3184
|
+
* - `deleteMany`
|
|
3185
|
+
* - `replaceOne`
|
|
3186
|
+
*
|
|
3174
3187
|
* @param {Array} ops
|
|
3188
|
+
* @param {Object} [ops.insertOne.document] The document to insert
|
|
3189
|
+
* @param {Object} [opts.updateOne.filter] Update the first document that matches this filter
|
|
3190
|
+
* @param {Object} [opts.updateOne.update] An object containing [update operators](https://docs.mongodb.com/manual/reference/operator/update/)
|
|
3191
|
+
* @param {Boolean} [opts.updateOne.upsert=false] If true, insert a doc if none match
|
|
3192
|
+
* @param {Object} [opts.updateOne.collation] The [MongoDB collation](https://thecodebarbarian.com/a-nodejs-perspective-on-mongodb-34-collations) to use
|
|
3193
|
+
* @param {Array} [opts.updateOne.arrayFilters] The [array filters](https://thecodebarbarian.com/a-nodejs-perspective-on-mongodb-36-array-filters.html) used in `update`
|
|
3194
|
+
* @param {Object} [opts.updateMany.filter] Update all the documents that match this filter
|
|
3195
|
+
* @param {Object} [opts.updateMany.update] An object containing [update operators](https://docs.mongodb.com/manual/reference/operator/update/)
|
|
3196
|
+
* @param {Boolean} [opts.updateMany.upsert=false] If true, insert a doc if no documents match `filter`
|
|
3197
|
+
* @param {Object} [opts.updateMany.collation] The [MongoDB collation](https://thecodebarbarian.com/a-nodejs-perspective-on-mongodb-34-collations) to use
|
|
3198
|
+
* @param {Array} [opts.updateMany.arrayFilters] The [array filters](https://thecodebarbarian.com/a-nodejs-perspective-on-mongodb-36-array-filters.html) used in `update`
|
|
3199
|
+
* @param {Object} [opts.deleteOne.filter] Delete the first document that matches this filter
|
|
3200
|
+
* @param {Object} [opts.deleteMany.filter] Delete all documents that match this filter
|
|
3201
|
+
* @param {Object} [opts.replaceOne.filter] Replace the first document that matches this filter
|
|
3202
|
+
* @param {Object} [opts.replaceOne.replacement] The replacement document
|
|
3203
|
+
* @param {Boolean} [opts.replaceOne.upsert=false] If true, insert a doc if no documents match `filter`
|
|
3175
3204
|
* @param {Object} [options]
|
|
3176
3205
|
* @param {Boolean} [options.ordered=true] If true, execute writes in order and stop at the first error. If false, execute writes in parallel and continue until all writes have either succeeded or errored.
|
|
3177
3206
|
* @param {ClientSession} [options.session=null] The session associated with this bulk write. See [transactions docs](/docs/transactions.html).
|
|
@@ -3308,9 +3337,17 @@ Model.hydrate = function(obj) {
|
|
|
3308
3337
|
* @param {Object} conditions
|
|
3309
3338
|
* @param {Object} doc
|
|
3310
3339
|
* @param {Object} [options] optional see [`Query.prototype.setOptions()`](http://mongoosejs.com/docs/api.html#query_Query-setOptions)
|
|
3340
|
+
* @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](http://mongoosejs.com/docs/guide.html#strict)
|
|
3341
|
+
* @param {Boolean} [options.upsert=false] if true, and no documents found, insert a new document
|
|
3342
|
+
* @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)
|
|
3343
|
+
* @param {Boolean} [options.omitUndefined=false] If true, delete any properties whose value is `undefined` when casting an update. In other words, if this is set, Mongoose will delete `baz` from the update in `Model.updateOne({}, { foo: 'bar', baz: undefined })` before sending the update to the server.
|
|
3344
|
+
* @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.
|
|
3345
|
+
* @param {Function} [callback] params are (error, writeOpResult)
|
|
3311
3346
|
* @param {Function} [callback]
|
|
3312
3347
|
* @return {Query}
|
|
3313
3348
|
* @see MongoDB docs https://docs.mongodb.com/manual/reference/command/update/#update-command-output
|
|
3349
|
+
* @see writeOpResult http://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#~WriteOpResult
|
|
3350
|
+
* @see Query docs https://mongoosejs.com/docs/queries.html
|
|
3314
3351
|
* @api public
|
|
3315
3352
|
*/
|
|
3316
3353
|
|
|
@@ -3339,10 +3376,15 @@ Model.update = function update(conditions, doc, options, callback) {
|
|
|
3339
3376
|
* @param {Object} doc
|
|
3340
3377
|
* @param {Object} [options] optional see [`Query.prototype.setOptions()`](http://mongoosejs.com/docs/api.html#query_Query-setOptions)
|
|
3341
3378
|
* @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](http://mongoosejs.com/docs/guide.html#strict)
|
|
3379
|
+
* @param {Boolean} [options.upsert=false] if true, and no documents found, insert a new document
|
|
3380
|
+
* @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)
|
|
3342
3381
|
* @param {Boolean} [options.omitUndefined=false] If true, delete any properties whose value is `undefined` when casting an update. In other words, if this is set, Mongoose will delete `baz` from the update in `Model.updateOne({}, { foo: 'bar', baz: undefined })` before sending the update to the server.
|
|
3343
|
-
* @param {
|
|
3382
|
+
* @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.
|
|
3383
|
+
* @param {Function} [callback] `function(error, res) {}` where `res` has 3 properties: `n`, `nModified`, `ok`.
|
|
3344
3384
|
* @return {Query}
|
|
3385
|
+
* @see Query docs https://mongoosejs.com/docs/queries.html
|
|
3345
3386
|
* @see MongoDB docs https://docs.mongodb.com/manual/reference/command/update/#update-command-output
|
|
3387
|
+
* @see writeOpResult http://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#~WriteOpResult
|
|
3346
3388
|
* @api public
|
|
3347
3389
|
*/
|
|
3348
3390
|
|
|
@@ -3370,10 +3412,15 @@ Model.updateMany = function updateMany(conditions, doc, options, callback) {
|
|
|
3370
3412
|
* @param {Object} doc
|
|
3371
3413
|
* @param {Object} [options] optional see [`Query.prototype.setOptions()`](http://mongoosejs.com/docs/api.html#query_Query-setOptions)
|
|
3372
3414
|
* @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](http://mongoosejs.com/docs/guide.html#strict)
|
|
3415
|
+
* @param {Boolean} [options.upsert=false] if true, and no documents found, insert a new document
|
|
3416
|
+
* @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)
|
|
3373
3417
|
* @param {Boolean} [options.omitUndefined=false] If true, delete any properties whose value is `undefined` when casting an update. In other words, if this is set, Mongoose will delete `baz` from the update in `Model.updateOne({}, { foo: 'bar', baz: undefined })` before sending the update to the server.
|
|
3374
|
-
* @param {
|
|
3418
|
+
* @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.
|
|
3419
|
+
* @param {Function} [callback] params are (error, writeOpResult)
|
|
3375
3420
|
* @return {Query}
|
|
3421
|
+
* @see Query docs https://mongoosejs.com/docs/queries.html
|
|
3376
3422
|
* @see MongoDB docs https://docs.mongodb.com/manual/reference/command/update/#update-command-output
|
|
3423
|
+
* @see writeOpResult http://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#~WriteOpResult
|
|
3377
3424
|
* @api public
|
|
3378
3425
|
*/
|
|
3379
3426
|
|
|
@@ -3398,8 +3445,14 @@ Model.updateOne = function updateOne(conditions, doc, options, callback) {
|
|
|
3398
3445
|
* @param {Object} doc
|
|
3399
3446
|
* @param {Object} [options] optional see [`Query.prototype.setOptions()`](http://mongoosejs.com/docs/api.html#query_Query-setOptions)
|
|
3400
3447
|
* @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](http://mongoosejs.com/docs/guide.html#strict)
|
|
3448
|
+
* @param {Boolean} [options.upsert=false] if true, and no documents found, insert a new document
|
|
3449
|
+
* @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)
|
|
3401
3450
|
* @param {Boolean} [options.omitUndefined=false] If true, delete any properties whose value is `undefined` when casting an update. In other words, if this is set, Mongoose will delete `baz` from the update in `Model.updateOne({}, { foo: 'bar', baz: undefined })` before sending the update to the server.
|
|
3402
|
-
* @param {
|
|
3451
|
+
* @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.
|
|
3452
|
+
* @param {Function} [callback] `function(error, res) {}` where `res` has 3 properties: `n`, `nModified`, `ok`.
|
|
3453
|
+
* @return {Query}
|
|
3454
|
+
* @see Query docs https://mongoosejs.com/docs/queries.html
|
|
3455
|
+
* @see writeOpResult http://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#~WriteOpResult
|
|
3403
3456
|
* @return {Query}
|
|
3404
3457
|
* @api public
|
|
3405
3458
|
*/
|
|
@@ -4440,8 +4493,8 @@ function convertTo_id(val) {
|
|
|
4440
4493
|
val[i] = val[i]._id;
|
|
4441
4494
|
}
|
|
4442
4495
|
}
|
|
4443
|
-
if (val.isMongooseArray && val
|
|
4444
|
-
return val.
|
|
4496
|
+
if (val.isMongooseArray && val.$schema()) {
|
|
4497
|
+
return val.$schema().cast(val, val.$parent());
|
|
4445
4498
|
}
|
|
4446
4499
|
|
|
4447
4500
|
return [].concat(val);
|
|
@@ -4550,7 +4603,8 @@ Model.compile = function compile(name, schema, collectionName, connection, base)
|
|
|
4550
4603
|
|
|
4551
4604
|
const collectionOptions = {
|
|
4552
4605
|
bufferCommands: bufferCommands,
|
|
4553
|
-
capped: schema.options.capped
|
|
4606
|
+
capped: schema.options.capped,
|
|
4607
|
+
Promise: model.base.Promise
|
|
4554
4608
|
};
|
|
4555
4609
|
|
|
4556
4610
|
model.prototype.collection = connection.collection(
|
package/lib/query.js
CHANGED
|
@@ -3118,16 +3118,17 @@ Query.prototype._findOneAndDelete = wrapThunk(function(callback) {
|
|
|
3118
3118
|
*
|
|
3119
3119
|
* ####Examples
|
|
3120
3120
|
*
|
|
3121
|
-
* A.where().findOneAndReplace(
|
|
3122
|
-
* A.where().findOneAndReplace(
|
|
3123
|
-
* A.where().findOneAndReplace(
|
|
3124
|
-
* A.where().findOneAndReplace(
|
|
3125
|
-
* A.where().findOneAndReplace(callback)
|
|
3126
|
-
* A.where().findOneAndReplace()
|
|
3121
|
+
* A.where().findOneAndReplace(filter, replacement, options, callback); // executes
|
|
3122
|
+
* A.where().findOneAndReplace(filter, replacement, options); // return Query
|
|
3123
|
+
* A.where().findOneAndReplace(filter, replacement, callback); // executes
|
|
3124
|
+
* A.where().findOneAndReplace(filter); // returns Query
|
|
3125
|
+
* A.where().findOneAndReplace(callback); // executes
|
|
3126
|
+
* A.where().findOneAndReplace(); // returns Query
|
|
3127
3127
|
*
|
|
3128
3128
|
* @method findOneAndReplace
|
|
3129
3129
|
* @memberOf Query
|
|
3130
|
-
* @param {Object} [
|
|
3130
|
+
* @param {Object} [filter]
|
|
3131
|
+
* @param {Object} [replacement]
|
|
3131
3132
|
* @param {Object} [options]
|
|
3132
3133
|
* @param {Boolean} [options.rawResult] if true, returns the [raw result from the MongoDB driver](http://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#findAndModify)
|
|
3133
3134
|
* @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](http://mongoosejs.com/docs/guide.html#strict)
|
|
@@ -3138,28 +3139,39 @@ Query.prototype._findOneAndDelete = wrapThunk(function(callback) {
|
|
|
3138
3139
|
* @api public
|
|
3139
3140
|
*/
|
|
3140
3141
|
|
|
3141
|
-
Query.prototype.findOneAndReplace = function(
|
|
3142
|
+
Query.prototype.findOneAndReplace = function(filter, replacement, options, callback) {
|
|
3142
3143
|
this.op = 'findOneAndReplace';
|
|
3143
3144
|
this._validate();
|
|
3144
3145
|
|
|
3145
3146
|
switch (arguments.length) {
|
|
3146
|
-
case
|
|
3147
|
+
case 3:
|
|
3147
3148
|
if (typeof options === 'function') {
|
|
3148
3149
|
callback = options;
|
|
3149
|
-
options =
|
|
3150
|
+
options = void 0;
|
|
3151
|
+
}
|
|
3152
|
+
break;
|
|
3153
|
+
case 2:
|
|
3154
|
+
if (typeof replacement === 'function') {
|
|
3155
|
+
callback = replacement;
|
|
3156
|
+
replacement = void 0;
|
|
3150
3157
|
}
|
|
3151
3158
|
break;
|
|
3152
3159
|
case 1:
|
|
3153
|
-
if (typeof
|
|
3154
|
-
callback =
|
|
3155
|
-
|
|
3156
|
-
|
|
3160
|
+
if (typeof filter === 'function') {
|
|
3161
|
+
callback = filter;
|
|
3162
|
+
filter = void 0;
|
|
3163
|
+
replacement = void 0;
|
|
3164
|
+
options = void 0;
|
|
3157
3165
|
}
|
|
3158
3166
|
break;
|
|
3159
3167
|
}
|
|
3160
3168
|
|
|
3161
|
-
if (mquery.canMerge(
|
|
3162
|
-
this.merge(
|
|
3169
|
+
if (mquery.canMerge(filter)) {
|
|
3170
|
+
this.merge(filter);
|
|
3171
|
+
}
|
|
3172
|
+
|
|
3173
|
+
if (replacement != null) {
|
|
3174
|
+
this._mergeUpdate(replacement);
|
|
3163
3175
|
}
|
|
3164
3176
|
|
|
3165
3177
|
options && this.setOptions(options);
|
|
@@ -3419,12 +3431,7 @@ Query.prototype._findAndModify = function(type, callback) {
|
|
|
3419
3431
|
if (error) {
|
|
3420
3432
|
return callback(error);
|
|
3421
3433
|
}
|
|
3422
|
-
|
|
3423
|
-
castedDoc = castedDoc.toBSON();
|
|
3424
|
-
}
|
|
3425
|
-
_this._collection.findAndModify(castedQuery, castedDoc, opts, _wrapThunkCallback(_this, function(error, res) {
|
|
3426
|
-
return cb(error, res ? res.value : res, res);
|
|
3427
|
-
}));
|
|
3434
|
+
_legacyFindAndModify.call(_this, castedQuery, castedDoc, opts, cb);
|
|
3428
3435
|
};
|
|
3429
3436
|
|
|
3430
3437
|
try {
|
|
@@ -3433,12 +3440,7 @@ Query.prototype._findAndModify = function(type, callback) {
|
|
|
3433
3440
|
callback(error);
|
|
3434
3441
|
}
|
|
3435
3442
|
} else {
|
|
3436
|
-
|
|
3437
|
-
castedDoc = castedDoc.toBSON();
|
|
3438
|
-
}
|
|
3439
|
-
this._collection.findAndModify(castedQuery, castedDoc, opts, _wrapThunkCallback(_this, function(error, res) {
|
|
3440
|
-
return cb(error, res ? res.value : res, res);
|
|
3441
|
-
}));
|
|
3443
|
+
_legacyFindAndModify.call(_this, castedQuery, castedDoc, opts, cb);
|
|
3442
3444
|
}
|
|
3443
3445
|
|
|
3444
3446
|
return this;
|
|
@@ -3455,6 +3457,23 @@ function _completeOneLean(doc, res, opts, callback) {
|
|
|
3455
3457
|
return callback(null, doc);
|
|
3456
3458
|
}
|
|
3457
3459
|
|
|
3460
|
+
|
|
3461
|
+
/*!
|
|
3462
|
+
* ignore
|
|
3463
|
+
*/
|
|
3464
|
+
|
|
3465
|
+
const _legacyFindAndModify = util.deprecate(function(filter, update, opts, cb) {
|
|
3466
|
+
if (update && update.toBSON) {
|
|
3467
|
+
update = update.toBSON();
|
|
3468
|
+
}
|
|
3469
|
+
const collection = this._collection;
|
|
3470
|
+
collection.findAndModify(filter, update, opts, _wrapThunkCallback(this, function(error, res) {
|
|
3471
|
+
return cb(error, res ? res.value : res, res);
|
|
3472
|
+
}));
|
|
3473
|
+
}, 'Mongoose: `findOneAndUpdate()` and `findOneAndDelete()` without the ' +
|
|
3474
|
+
'`useFindAndModify` option set to false are deprecated. See: ' +
|
|
3475
|
+
'https://mongoosejs.com/docs/deprecations.html#-findandmodify-');
|
|
3476
|
+
|
|
3458
3477
|
/*!
|
|
3459
3478
|
* Override mquery.prototype._mergeUpdate to handle mongoose objects in
|
|
3460
3479
|
* updates.
|
|
@@ -3716,9 +3735,16 @@ Query.prototype._replaceOne = wrapThunk(function(callback) {
|
|
|
3716
3735
|
* @param {Object} [doc] the update command
|
|
3717
3736
|
* @param {Object} [options]
|
|
3718
3737
|
* @param {Boolean} [options.multipleCastError] by default, mongoose only returns the first error that occurred in casting the query. Turn on this option to aggregate all the cast errors.
|
|
3719
|
-
* @param {
|
|
3738
|
+
* @param {Boolean} [options.omitUndefined=false] If true, delete any properties whose value is `undefined` when casting an update. In other words, if this is set, Mongoose will delete `baz` from the update in `Model.updateOne({}, { foo: 'bar', baz: undefined })` before sending the update to the server.
|
|
3739
|
+
* @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](http://mongoosejs.com/docs/guide.html#strict)
|
|
3740
|
+
* @param {Boolean} [options.upsert=false] if true, and no documents found, insert a new document
|
|
3741
|
+
* @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)
|
|
3742
|
+
* @param {Boolean} [options.omitUndefined=false] If true, delete any properties whose value is `undefined` when casting an update. In other words, if this is set, Mongoose will delete `baz` from the update in `Model.updateOne({}, { foo: 'bar', baz: undefined })` before sending the update to the server.
|
|
3743
|
+
* @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.
|
|
3744
|
+
* @param {Function} [callback] params are (error, writeOpResult)
|
|
3720
3745
|
* @return {Query} this
|
|
3721
3746
|
* @see Model.update #model_Model.update
|
|
3747
|
+
* @see Query docs https://mongoosejs.com/docs/queries.html
|
|
3722
3748
|
* @see update http://docs.mongodb.org/manual/reference/method/db.collection.update/
|
|
3723
3749
|
* @see writeOpResult http://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#~WriteOpResult
|
|
3724
3750
|
* @see MongoDB docs https://docs.mongodb.com/manual/reference/command/update/#update-command-output
|
|
@@ -3776,9 +3802,15 @@ Query.prototype.update = function(conditions, doc, options, callback) {
|
|
|
3776
3802
|
* @param {Object} [options]
|
|
3777
3803
|
* @param {Boolean} [options.multipleCastError] by default, mongoose only returns the first error that occurred in casting the query. Turn on this option to aggregate all the cast errors.
|
|
3778
3804
|
* @param {Boolean} [options.omitUndefined=false] If true, delete any properties whose value is `undefined` when casting an update. In other words, if this is set, Mongoose will delete `baz` from the update in `Model.updateOne({}, { foo: 'bar', baz: undefined })` before sending the update to the server.
|
|
3779
|
-
* @param {
|
|
3805
|
+
* @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](http://mongoosejs.com/docs/guide.html#strict)
|
|
3806
|
+
* @param {Boolean} [options.upsert=false] if true, and no documents found, insert a new document
|
|
3807
|
+
* @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)
|
|
3808
|
+
* @param {Boolean} [options.omitUndefined=false] If true, delete any properties whose value is `undefined` when casting an update. In other words, if this is set, Mongoose will delete `baz` from the update in `Model.updateOne({}, { foo: 'bar', baz: undefined })` before sending the update to the server.
|
|
3809
|
+
* @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.
|
|
3810
|
+
* @param {Function} [callback] params are (error, writeOpResult)
|
|
3780
3811
|
* @return {Query} this
|
|
3781
3812
|
* @see Model.update #model_Model.update
|
|
3813
|
+
* @see Query docs https://mongoosejs.com/docs/queries.html
|
|
3782
3814
|
* @see update http://docs.mongodb.org/manual/reference/method/db.collection.update/
|
|
3783
3815
|
* @see writeOpResult http://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#~WriteOpResult
|
|
3784
3816
|
* @see MongoDB docs https://docs.mongodb.com/manual/reference/command/update/#update-command-output
|
|
@@ -3837,9 +3869,15 @@ Query.prototype.updateMany = function(conditions, doc, options, callback) {
|
|
|
3837
3869
|
* @param {Object} [options]
|
|
3838
3870
|
* @param {Boolean} [options.multipleCastError] by default, mongoose only returns the first error that occurred in casting the query. Turn on this option to aggregate all the cast errors.
|
|
3839
3871
|
* @param {Boolean} [options.omitUndefined=false] If true, delete any properties whose value is `undefined` when casting an update. In other words, if this is set, Mongoose will delete `baz` from the update in `Model.updateOne({}, { foo: 'bar', baz: undefined })` before sending the update to the server.
|
|
3872
|
+
* @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](http://mongoosejs.com/docs/guide.html#strict)
|
|
3873
|
+
* @param {Boolean} [options.upsert=false] if true, and no documents found, insert a new document
|
|
3874
|
+
* @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)
|
|
3875
|
+
* @param {Boolean} [options.omitUndefined=false] If true, delete any properties whose value is `undefined` when casting an update. In other words, if this is set, Mongoose will delete `baz` from the update in `Model.updateOne({}, { foo: 'bar', baz: undefined })` before sending the update to the server.
|
|
3876
|
+
* @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.
|
|
3840
3877
|
* @param {Function} [callback] params are (error, writeOpResult)
|
|
3841
3878
|
* @return {Query} this
|
|
3842
3879
|
* @see Model.update #model_Model.update
|
|
3880
|
+
* @see Query docs https://mongoosejs.com/docs/queries.html
|
|
3843
3881
|
* @see update http://docs.mongodb.org/manual/reference/method/db.collection.update/
|
|
3844
3882
|
* @see writeOpResult http://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#~WriteOpResult
|
|
3845
3883
|
* @see MongoDB docs https://docs.mongodb.com/manual/reference/command/update/#update-command-output
|
|
@@ -3894,10 +3932,17 @@ Query.prototype.updateOne = function(conditions, doc, options, callback) {
|
|
|
3894
3932
|
* @param {Object} [criteria]
|
|
3895
3933
|
* @param {Object} [doc] the update command
|
|
3896
3934
|
* @param {Object} [options]
|
|
3935
|
+
* @param {Boolean} [options.multipleCastError] by default, mongoose only returns the first error that occurred in casting the query. Turn on this option to aggregate all the cast errors.
|
|
3897
3936
|
* @param {Boolean} [options.omitUndefined=false] If true, delete any properties whose value is `undefined` when casting an update. In other words, if this is set, Mongoose will delete `baz` from the update in `Model.updateOne({}, { foo: 'bar', baz: undefined })` before sending the update to the server.
|
|
3898
|
-
* @param {
|
|
3937
|
+
* @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](http://mongoosejs.com/docs/guide.html#strict)
|
|
3938
|
+
* @param {Boolean} [options.upsert=false] if true, and no documents found, insert a new document
|
|
3939
|
+
* @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)
|
|
3940
|
+
* @param {Boolean} [options.omitUndefined=false] If true, delete any properties whose value is `undefined` when casting an update. In other words, if this is set, Mongoose will delete `baz` from the update in `Model.updateOne({}, { foo: 'bar', baz: undefined })` before sending the update to the server.
|
|
3941
|
+
* @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.
|
|
3942
|
+
* @param {Function} [callback] params are (error, writeOpResult)
|
|
3899
3943
|
* @return {Query} this
|
|
3900
3944
|
* @see Model.update #model_Model.update
|
|
3945
|
+
* @see Query docs https://mongoosejs.com/docs/queries.html
|
|
3901
3946
|
* @see update http://docs.mongodb.org/manual/reference/method/db.collection.update/
|
|
3902
3947
|
* @see writeOpResult http://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#~WriteOpResult
|
|
3903
3948
|
* @see MongoDB docs https://docs.mongodb.com/manual/reference/command/update/#update-command-output
|
package/lib/schema/array.js
CHANGED
|
@@ -146,6 +146,56 @@ SchemaArray.options = { castNonArrays: true };
|
|
|
146
146
|
SchemaArray.prototype = Object.create(SchemaType.prototype);
|
|
147
147
|
SchemaArray.prototype.constructor = SchemaArray;
|
|
148
148
|
|
|
149
|
+
/*!
|
|
150
|
+
* ignore
|
|
151
|
+
*/
|
|
152
|
+
|
|
153
|
+
SchemaArray._checkRequired = SchemaType.prototype.checkRequired;
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Override the function the required validator uses to check whether an array
|
|
157
|
+
* passes the `required` check.
|
|
158
|
+
*
|
|
159
|
+
* ####Example:
|
|
160
|
+
*
|
|
161
|
+
* // Require non-empty array to pass `required` check
|
|
162
|
+
* mongoose.Schema.Types.Array.checkRequired(v => Array.isArray(v) && v.length);
|
|
163
|
+
*
|
|
164
|
+
* const M = mongoose.model({ arr: { type: Array, required: true } });
|
|
165
|
+
* new M({ arr: [] }).validateSync(); // `null`, validation fails!
|
|
166
|
+
*
|
|
167
|
+
* @param {Function} fn
|
|
168
|
+
* @return {Function}
|
|
169
|
+
* @function checkRequired
|
|
170
|
+
* @static
|
|
171
|
+
* @api public
|
|
172
|
+
*/
|
|
173
|
+
|
|
174
|
+
SchemaArray.checkRequired = SchemaType.checkRequired;
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Check if the given value satisfies the `required` validator.
|
|
178
|
+
*
|
|
179
|
+
* @param {Any} value
|
|
180
|
+
* @param {Document} doc
|
|
181
|
+
* @return {Boolean}
|
|
182
|
+
* @api public
|
|
183
|
+
*/
|
|
184
|
+
|
|
185
|
+
SchemaArray.prototype.checkRequired = function checkRequired(value, doc) {
|
|
186
|
+
if (SchemaType._isRef(this, value, doc, true)) {
|
|
187
|
+
return !!value;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// `require('util').inherits()` does **not** copy static properties, and
|
|
191
|
+
// plugins like mongoose-float use `inherits()` for pre-ES6.
|
|
192
|
+
const _checkRequired = typeof this.constructor.checkRequired == 'function' ?
|
|
193
|
+
this.constructor.checkRequired() :
|
|
194
|
+
SchemaArray.checkRequired();
|
|
195
|
+
|
|
196
|
+
return _checkRequired(value);
|
|
197
|
+
};
|
|
198
|
+
|
|
149
199
|
/**
|
|
150
200
|
* Adds an enum validator if this is an array of strings. Equivalent to
|
|
151
201
|
* `SchemaString.prototype.enum()`
|
|
@@ -13,6 +13,8 @@ const util = require('util');
|
|
|
13
13
|
const utils = require('../utils');
|
|
14
14
|
const getDiscriminatorByValue = require('../queryhelpers').getDiscriminatorByValue;
|
|
15
15
|
|
|
16
|
+
const arrayParentSymbol = require('../helpers/symbols').arrayParentSymbol;
|
|
17
|
+
|
|
16
18
|
let MongooseDocumentArray;
|
|
17
19
|
let Subdocument;
|
|
18
20
|
|
|
@@ -207,8 +209,8 @@ DocumentArray.prototype.doValidate = function(array, fn, scope, options) {
|
|
|
207
209
|
// If you set the array index directly, the doc might not yet be
|
|
208
210
|
// a full fledged mongoose subdoc, so make it into one.
|
|
209
211
|
if (!(doc instanceof Subdocument)) {
|
|
210
|
-
|
|
211
|
-
|
|
212
|
+
const Constructor = getConstructor(_this, array[i]);
|
|
213
|
+
doc = array[i] = new Constructor(doc, array, undefined, undefined, i);
|
|
212
214
|
}
|
|
213
215
|
|
|
214
216
|
doc.$__validate(callback);
|
|
@@ -255,8 +257,8 @@ DocumentArray.prototype.doValidateSync = function(array, scope) {
|
|
|
255
257
|
// If you set the array index directly, the doc might not yet be
|
|
256
258
|
// a full fledged mongoose subdoc, so make it into one.
|
|
257
259
|
if (!(doc instanceof Subdocument)) {
|
|
258
|
-
|
|
259
|
-
|
|
260
|
+
const Constructor = getConstructor(this, array[i]);
|
|
261
|
+
doc = array[i] = new Constructor(doc, array, undefined, undefined, i);
|
|
260
262
|
}
|
|
261
263
|
|
|
262
264
|
const subdocValidateError = doc.validateSync();
|
|
@@ -290,15 +292,16 @@ DocumentArray.prototype.getDefault = function(scope) {
|
|
|
290
292
|
}
|
|
291
293
|
|
|
292
294
|
ret = new MongooseDocumentArray(ret, this.path, scope);
|
|
293
|
-
const _parent = ret
|
|
294
|
-
ret
|
|
295
|
+
const _parent = ret[arrayParentSymbol];
|
|
296
|
+
ret[arrayParentSymbol] = null;
|
|
295
297
|
|
|
296
298
|
for (let i = 0; i < ret.length; ++i) {
|
|
297
|
-
|
|
299
|
+
const Constructor = getConstructor(this, ret[i]);
|
|
300
|
+
ret[i] = new Constructor(ret[i], ret, undefined,
|
|
298
301
|
undefined, i);
|
|
299
302
|
}
|
|
300
303
|
|
|
301
|
-
ret
|
|
304
|
+
ret[arrayParentSymbol] = _parent;
|
|
302
305
|
|
|
303
306
|
return ret;
|
|
304
307
|
};
|
|
@@ -349,30 +352,19 @@ DocumentArray.prototype.cast = function(value, doc, init, prev, options) {
|
|
|
349
352
|
continue;
|
|
350
353
|
}
|
|
351
354
|
|
|
352
|
-
|
|
353
|
-
if (Constructor.discriminators &&
|
|
354
|
-
Constructor.schema &&
|
|
355
|
-
Constructor.schema.options &&
|
|
356
|
-
typeof value[i][Constructor.schema.options.discriminatorKey] === 'string') {
|
|
357
|
-
if (Constructor.discriminators[value[i][Constructor.schema.options.discriminatorKey]]) {
|
|
358
|
-
Constructor = Constructor.discriminators[value[i][Constructor.schema.options.discriminatorKey]];
|
|
359
|
-
} else {
|
|
360
|
-
const constructorByValue = getDiscriminatorByValue(Constructor, value[i][Constructor.schema.options.discriminatorKey]);
|
|
361
|
-
if (constructorByValue) {
|
|
362
|
-
Constructor = constructorByValue;
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
}
|
|
355
|
+
const Constructor = getConstructor(this, value[i]);
|
|
366
356
|
|
|
367
357
|
// Check if the document has a different schema (re gh-3701)
|
|
368
358
|
if ((value[i].$__) &&
|
|
369
|
-
value[i]
|
|
359
|
+
!(value[i] instanceof Constructor)) {
|
|
370
360
|
value[i] = value[i].toObject({ transform: false, virtuals: false });
|
|
371
361
|
}
|
|
372
362
|
|
|
373
363
|
if (value[i] instanceof Subdocument) {
|
|
374
364
|
// Might not have the correct index yet, so ensure it does.
|
|
375
|
-
value[i]
|
|
365
|
+
if (value[i].__index == null) {
|
|
366
|
+
value[i].$setIndex(i);
|
|
367
|
+
}
|
|
376
368
|
} else if (value[i] != null) {
|
|
377
369
|
if (init) {
|
|
378
370
|
if (doc) {
|
|
@@ -417,6 +409,30 @@ DocumentArray.prototype.cast = function(value, doc, init, prev, options) {
|
|
|
417
409
|
return value;
|
|
418
410
|
};
|
|
419
411
|
|
|
412
|
+
/*!
|
|
413
|
+
* Find the correct subdoc constructor, taking into account discriminators
|
|
414
|
+
*/
|
|
415
|
+
|
|
416
|
+
function getConstructor(docArray, subdoc) {
|
|
417
|
+
let Constructor = docArray.casterConstructor;
|
|
418
|
+
const schema = Constructor.schema;
|
|
419
|
+
const discriminatorKey = schema.options.discriminatorKey;
|
|
420
|
+
const discriminatorValue = subdoc[discriminatorKey];
|
|
421
|
+
if (Constructor.discriminators && typeof discriminatorValue === 'string') {
|
|
422
|
+
if (Constructor.discriminators[discriminatorValue]) {
|
|
423
|
+
Constructor = Constructor.discriminators[discriminatorValue];
|
|
424
|
+
} else {
|
|
425
|
+
const constructorByValue = getDiscriminatorByValue(Constructor,
|
|
426
|
+
discriminatorValue);
|
|
427
|
+
if (constructorByValue) {
|
|
428
|
+
Constructor = constructorByValue;
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
return Constructor;
|
|
434
|
+
}
|
|
435
|
+
|
|
420
436
|
/*!
|
|
421
437
|
* ignore
|
|
422
438
|
*/
|
|
@@ -432,12 +448,12 @@ DocumentArray.prototype.clone = function() {
|
|
|
432
448
|
*/
|
|
433
449
|
|
|
434
450
|
function _clearListeners(arr) {
|
|
435
|
-
if (arr == null || arr
|
|
451
|
+
if (arr == null || arr[arrayParentSymbol] == null) {
|
|
436
452
|
return;
|
|
437
453
|
}
|
|
438
454
|
|
|
439
455
|
for (const key in arr._handlers) {
|
|
440
|
-
arr.
|
|
456
|
+
arr[arrayParentSymbol].removeListener(key, arr._handlers[key]);
|
|
441
457
|
}
|
|
442
458
|
}
|
|
443
459
|
|
package/lib/schema.js
CHANGED
|
@@ -1049,11 +1049,12 @@ Schema.prototype.setupTimestamp = function(timestamps) {
|
|
|
1049
1049
|
|
|
1050
1050
|
_setTimestampsOnUpdate[symbols.builtInMiddleware] = true;
|
|
1051
1051
|
|
|
1052
|
-
|
|
1053
|
-
this.pre('
|
|
1054
|
-
this.pre('
|
|
1055
|
-
this.pre('
|
|
1056
|
-
this.pre('
|
|
1052
|
+
const opts = { query: true, model: false };
|
|
1053
|
+
this.pre('findOneAndUpdate', opts, _setTimestampsOnUpdate);
|
|
1054
|
+
this.pre('replaceOne', opts, _setTimestampsOnUpdate);
|
|
1055
|
+
this.pre('update', opts, _setTimestampsOnUpdate);
|
|
1056
|
+
this.pre('updateOne', opts, _setTimestampsOnUpdate);
|
|
1057
|
+
this.pre('updateMany', opts, _setTimestampsOnUpdate);
|
|
1057
1058
|
|
|
1058
1059
|
function _setTimestampsOnUpdate(next) {
|
|
1059
1060
|
const now = this.model.base.now();
|