diff --git a/lib/schema/SubdocumentPath.js b/lib/schema/SubdocumentPath.js index d3066839831..9486a302248 100644 --- a/lib/schema/SubdocumentPath.js +++ b/lib/schema/SubdocumentPath.js @@ -17,6 +17,7 @@ const geospatial = require('./operators/geospatial'); const getConstructor = require('../helpers/discriminator/getConstructor'); const handleIdOption = require('../helpers/schema/handleIdOption'); const internalToObjectOptions = require('../options').internalToObjectOptions; +const isExclusive = require('../helpers/projection/isExclusive'); const utils = require('../utils'); let Subdocument; @@ -173,7 +174,8 @@ SubdocumentPath.prototype.cast = function(val, doc, init, priorVal, options) { subdoc = new Constructor(void 0, selected, doc, false, { defaults: false }); delete subdoc.$__.defaults; subdoc.$init(val); - applyDefaults(subdoc, selected); + const exclude = isExclusive(selected); + applyDefaults(subdoc, selected, exclude); } else { options = Object.assign({}, options, { priorDoc: priorVal }); if (Object.keys(val).length === 0) { diff --git a/test/document.test.js b/test/document.test.js index 5eb33c0f86f..f81adace7dc 100644 --- a/test/document.test.js +++ b/test/document.test.js @@ -12296,6 +12296,22 @@ describe('document', function() { assert.strictEqual(test.polluted, undefined); assert.strictEqual(Object.prototype.polluted, undefined); }); + + it('sets defaults on subdocs with subdoc projection (gh-13720)', async function() { + const subSchema = new mongoose.Schema({ + propertyA: { type: String, default: 'A' }, + propertyB: { type: String, default: 'B' } + }); + const userSchema = new mongoose.Schema({ + name: String, + sub: { type: subSchema, default: () => ({}) } + }); + const User = db.model('User', userSchema); + await User.insertMany([{ name: 'user' }]); + await User.updateMany({}, { $unset: { 'sub.propertyA': '' } }); + const nestedProjectionDoc = await User.findOne({}, { name: 1, 'sub.propertyA': 1, 'sub.propertyB': 1 }); + assert.strictEqual(nestedProjectionDoc.sub.propertyA, 'A'); + }); }); describe('Check if instance function that is supplied in schema option is availabe', function() { diff --git a/types/augmentations.d.ts b/types/augmentations.d.ts index fe72cb1aa3f..82aca589ff8 100644 --- a/types/augmentations.d.ts +++ b/types/augmentations.d.ts @@ -6,4 +6,4 @@ declare module 'bson' { /** Mongoose automatically adds a conveniency "_id" getter on the base ObjectId class */ _id: this; } -} \ No newline at end of file +}