diff --git a/lib/model.js b/lib/model.js index f5e4f12f967..0d8cdf7cfd1 100644 --- a/lib/model.js +++ b/lib/model.js @@ -375,7 +375,9 @@ Model.prototype.$__handleSave = function(options, callback) { } minimize(updateOp[key]); if (Object.keys(updateOp[key]).length === 0) { - updateOp[key] = null; + delete updateOp[key]; + update.$unset = update.$unset || {}; + update.$unset[key] = 1; } } } diff --git a/test/document.test.js b/test/document.test.js index 8e0868dffbb..6e125b82fc0 100644 --- a/test/document.test.js +++ b/test/document.test.js @@ -13060,8 +13060,8 @@ describe('document', function() { x.metadata = {}; await x.save(); - const { metadata } = await Model.findById(m._id).orFail(); - assert.strictEqual(metadata, null); + const { metadata } = await Model.findById(m._id).lean().orFail(); + assert.strictEqual(metadata, undefined); }); it('saves when setting subdocument to empty object (gh-14420) (gh-13782)', async function() { @@ -13085,7 +13085,7 @@ describe('document', function() { await doc.save(); const savedDoc = await MainModel.findById(doc.id).orFail(); - assert.strictEqual(savedDoc.sub, null); + assert.strictEqual(savedDoc.sub, undefined); }); it('validate supports validateAllPaths', async function() { @@ -13205,6 +13205,37 @@ describe('document', function() { err.errors['docArr.0.subprop'].message ); }); + + it('minimize unsets property rather than setting to null (gh-14445)', async function() { + const SubSchema = new mongoose.Schema({ + name: { type: String } + }, { _id: false }); + + const MainSchema = new mongoose.Schema({ + name: String, + sub: { + type: SubSchema, + default: {} + } + }); + + const Test = db.model('Test', MainSchema); + const doc = new Test({ name: 'foo' }); + await doc.save(); + + const savedDocFirst = await Test.findById(doc.id).orFail(); + assert.deepStrictEqual(savedDocFirst.toObject({ minimize: false }).sub, {}); + + savedDocFirst.name = 'bar'; + await savedDocFirst.save(); + + const lean = await Test.findById(doc.id).lean().orFail(); + assert.strictEqual(lean.sub, undefined); + + const savedDocSecond = await Test.findById(doc.id).orFail(); + assert.deepStrictEqual(savedDocSecond.toObject({ minimize: false }).sub, {}); + + }); }); describe('Check if instance function that is supplied in schema option is availabe', function() {