diff --git a/lib/query.js b/lib/query.js index e7e7f046cbb..7dfb64fc2fc 100644 --- a/lib/query.js +++ b/lib/query.js @@ -3289,19 +3289,15 @@ Query.prototype._findOneAndUpdate = async function _findOneAndUpdate() { throw this.error(); } - this._applyPaths(); - this._fields = this._castFields(this._fields); applyGlobalMaxTimeMS(this.options, this.model); applyGlobalDiskUse(this.options, this.model); - const opts = this._optionsForExec(this.model); - this._applyTranslateAliases(opts); - - if ('strict' in opts) { - this._mongooseOptions.strict = opts.strict; + if ('strict' in this.options) { + this._mongooseOptions.strict = this.options.strict; } - const options = { projection: this._fields, ...opts }; + const options = this._optionsForExec(this.model); convertNewToReturnDocument(options); + this._applyTranslateAliases(options); this._update = this._castUpdate(this._update, false); @@ -3312,7 +3308,7 @@ Query.prototype._findOneAndUpdate = async function _findOneAndUpdate() { this._update, _opts); if (!this._update || Object.keys(this._update).length === 0) { - if (opts.upsert) { + if (options.upsert) { // still need to do the upsert to empty doc const doc = clone(this._update); delete doc._id; @@ -3488,18 +3484,8 @@ Query.prototype._findOneAndDelete = async function _findOneAndDelete() { } const filter = this._conditions; - const options = this._optionsForExec(); + const options = this._optionsForExec(this.model); this._applyTranslateAliases(options); - let fields = null; - - this._applyPaths(); - if (this._fields != null) { - options.projection = this._castFields(clone(this._fields)); - fields = options.projection; - if (fields instanceof Error) { - throw fields; - } - } let res = await this._collection.collection.findOneAndDelete(filter, options); for (const fn of this._transforms) { diff --git a/test/model.findOneAndUpdate.test.js b/test/model.findOneAndUpdate.test.js index 43e3eea9ae1..4441b633c0f 100644 --- a/test/model.findOneAndUpdate.test.js +++ b/test/model.findOneAndUpdate.test.js @@ -2091,4 +2091,32 @@ describe('model: findOneAndUpdate:', function() { assert.equal(err.name, 'ObjectParameterError'); }); + it('handles plus path in projection (gh-13413)', async function() { + const testSchema = new mongoose.Schema({ + name: String, + nickName: { + type: String, + select: false + } + }); + const Test = db.model('Test', testSchema); + + const entry = await Test.create({ + name: 'Test Testerson', + nickName: 'Quiz' + }); + + let res = await Test.findOneAndUpdate( + { _id: entry._id }, + { $set: { name: 'Test' } }, + { projection: '+nickName', returnDocument: 'after' } + ); + assert.equal(res.nickName, 'Quiz'); + + res = await Test.findOneAndDelete( + { _id: entry._id }, + { projection: '+nickName', returnDocument: 'before' } + ); + assert.equal(res.nickName, 'Quiz'); + }); });