@@ -1748,6 +1748,10 @@ Query.prototype.setOptions = function(options, overwrite) {
1748
1748
this . _mongooseOptions . overwriteImmutable = options . overwriteImmutable ;
1749
1749
delete options . overwriteImmutable ;
1750
1750
}
1751
+ if ( 'updatePipeline' in options ) {
1752
+ this . _mongooseOptions . updatePipeline = options . updatePipeline ;
1753
+ delete options . updatePipeline ;
1754
+ }
1751
1755
if ( 'sanitizeProjection' in options ) {
1752
1756
if ( options . sanitizeProjection && ! this . _mongooseOptions . sanitizeProjection ) {
1753
1757
sanitizeProjection ( this . _fields ) ;
@@ -3385,7 +3389,7 @@ function prepareDiscriminatorCriteria(query) {
3385
3389
* @memberOf Query
3386
3390
* @instance
3387
3391
* @param {Object|Query } [filter]
3388
- * @param {Object } [doc ]
3392
+ * @param {Object } [update ]
3389
3393
* @param {Object } [options]
3390
3394
* @param {Boolean } [options.includeResultMetadata] if true, returns the full [ModifyResult from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/4.9/interfaces/ModifyResult.html) rather than just the document
3391
3395
* @param {Boolean|String } [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
@@ -3407,9 +3411,9 @@ function prepareDiscriminatorCriteria(query) {
3407
3411
* @api public
3408
3412
*/
3409
3413
3410
- Query . prototype . findOneAndUpdate = function ( filter , doc , options ) {
3414
+ Query . prototype . findOneAndUpdate = function ( filter , update , options ) {
3411
3415
if ( typeof filter === 'function' ||
3412
- typeof doc === 'function' ||
3416
+ typeof update === 'function' ||
3413
3417
typeof options === 'function' ||
3414
3418
typeof arguments [ 3 ] === 'function' ) {
3415
3419
throw new MongooseError ( 'Query.prototype.findOneAndUpdate() no longer accepts a callback' ) ;
@@ -3423,7 +3427,7 @@ Query.prototype.findOneAndUpdate = function(filter, doc, options) {
3423
3427
options = undefined ;
3424
3428
break ;
3425
3429
case 1 :
3426
- doc = filter ;
3430
+ update = filter ;
3427
3431
filter = options = undefined ;
3428
3432
break ;
3429
3433
}
@@ -3436,11 +3440,6 @@ Query.prototype.findOneAndUpdate = function(filter, doc, options) {
3436
3440
) ;
3437
3441
}
3438
3442
3439
- // apply doc
3440
- if ( doc ) {
3441
- this . _mergeUpdate ( doc ) ;
3442
- }
3443
-
3444
3443
options = options ? clone ( options ) : { } ;
3445
3444
3446
3445
if ( options . projection ) {
@@ -3463,6 +3462,11 @@ Query.prototype.findOneAndUpdate = function(filter, doc, options) {
3463
3462
3464
3463
this . setOptions ( options ) ;
3465
3464
3465
+ // apply doc
3466
+ if ( update ) {
3467
+ this . _mergeUpdate ( update ) ;
3468
+ }
3469
+
3466
3470
return this ;
3467
3471
} ;
3468
3472
@@ -3997,39 +4001,43 @@ function _completeManyLean(schema, docs, path, opts) {
3997
4001
* Override mquery.prototype._mergeUpdate to handle mongoose objects in
3998
4002
* updates.
3999
4003
*
4000
- * @param {Object } doc
4004
+ * @param {Object } update
4001
4005
* @method _mergeUpdate
4002
4006
* @memberOf Query
4003
4007
* @instance
4004
4008
* @api private
4005
4009
*/
4006
4010
4007
- Query . prototype . _mergeUpdate = function ( doc ) {
4011
+ Query . prototype . _mergeUpdate = function ( update ) {
4012
+ const updatePipeline = this . _mongooseOptions . updatePipeline ;
4013
+ if ( ! updatePipeline && Array . isArray ( update ) ) {
4014
+ throw new MongooseError ( 'Cannot pass an array to query updates unless the `updatePipeline` option is set.' ) ;
4015
+ }
4008
4016
if ( ! this . _update ) {
4009
- this . _update = Array . isArray ( doc ) ? [ ] : { } ;
4017
+ this . _update = Array . isArray ( update ) ? [ ] : { } ;
4010
4018
}
4011
4019
4012
- if ( doc == null || ( typeof doc === 'object' && Object . keys ( doc ) . length === 0 ) ) {
4020
+ if ( update == null || ( typeof update === 'object' && Object . keys ( update ) . length === 0 ) ) {
4013
4021
return ;
4014
4022
}
4015
4023
4016
- if ( doc instanceof Query ) {
4024
+ if ( update instanceof Query ) {
4017
4025
if ( Array . isArray ( this . _update ) ) {
4018
- throw new Error ( 'Cannot mix array and object updates' ) ;
4026
+ throw new MongooseError ( 'Cannot mix array and object updates' ) ;
4019
4027
}
4020
- if ( doc . _update ) {
4021
- utils . mergeClone ( this . _update , doc . _update ) ;
4028
+ if ( update . _update ) {
4029
+ utils . mergeClone ( this . _update , update . _update ) ;
4022
4030
}
4023
- } else if ( Array . isArray ( doc ) ) {
4031
+ } else if ( Array . isArray ( update ) ) {
4024
4032
if ( ! Array . isArray ( this . _update ) ) {
4025
- throw new Error ( 'Cannot mix array and object updates' ) ;
4033
+ throw new MongooseError ( 'Cannot mix array and object updates' ) ;
4026
4034
}
4027
- this . _update = this . _update . concat ( doc ) ;
4035
+ this . _update = this . _update . concat ( update ) ;
4028
4036
} else {
4029
4037
if ( Array . isArray ( this . _update ) ) {
4030
- throw new Error ( 'Cannot mix array and object updates' ) ;
4038
+ throw new MongooseError ( 'Cannot mix array and object updates' ) ;
4031
4039
}
4032
- utils . mergeClone ( this . _update , doc ) ;
4040
+ utils . mergeClone ( this . _update , update ) ;
4033
4041
}
4034
4042
} ;
4035
4043
0 commit comments