diff --git a/lib/document.js b/lib/document.js index b665b5cf821..731be3301c7 100644 --- a/lib/document.js +++ b/lib/document.js @@ -1162,7 +1162,7 @@ Document.prototype.$set = function $set(path, val, type, options) { // Assume this is a Mongoose document that was copied into a POJO using // `Object.assign()` or `{...doc}` - val = handleSpreadDoc(val); + val = handleSpreadDoc(val, true); // if this doc is being constructed we should not trigger getters const priorVal = (() => { diff --git a/test/document.test.js b/test/document.test.js index 382deb3d3c0..bd0de3fbb62 100644 --- a/test/document.test.js +++ b/test/document.test.js @@ -12916,6 +12916,43 @@ describe('document', function() { doc.set({ nested: void 0 }); assert.strictEqual(doc.toObject().nested, void 0); }); + + it('handles setting nested path to spread doc with extra properties (gh-14269)', async function() { + const addressSchema = new mongoose.Schema( + { + street: String, + city: String, + state: String, + zip: Number + }, + { _id: false } + ); + const personSchema = new mongoose.Schema({ + name: String, + age: Number, + address: addressSchema + }); + + const personModel = db.model('Person', personSchema); + const person = new personModel({ + name: 'John', + age: 42, + address: { + street: '123 Fake St', + city: 'Springfield', + state: 'IL', + zip: 12345 + } + }); + + await person.save(); + + person.address = { + ...person.address, + zip: 54321 + }; + assert.equal(person.address.zip, 54321); + }); }); describe('Check if instance function that is supplied in schema option is availabe', function() {