diff --git a/lib/model.js b/lib/model.js index 09abac417a7..8d9666df0ef 100644 --- a/lib/model.js +++ b/lib/model.js @@ -4298,6 +4298,8 @@ function populate(model, docs, options, callback) { // _id back off before returning the result. if (typeof select === 'string') { select = select.replace(excludeIdRegGlobal, ' '); + } else if (Array.isArray(select)) { + select = select.filter(field => field !== '-_id'); } else { // preserve original select conditions by copying select = { ...select }; diff --git a/test/model.populate.test.js b/test/model.populate.test.js index 1c6029853de..0a74994be3a 100644 --- a/test/model.populate.test.js +++ b/test/model.populate.test.js @@ -2197,7 +2197,7 @@ describe('model: populate:', function() { }); describe('in a subdocument', function() { - it('works', async function() { + it('works (gh-14231)', async function() { const docs = await U.find({ name: 'u1' }).populate('comments', { _id: 0 }); let doc = docs[0]; @@ -2229,6 +2229,15 @@ describe('model: populate:', function() { assert.equal(typeof d._doc.__v, 'number'); }); + doc = await U.findOne({ name: 'u1' }).populate('comments', ['-_id']); + assert.equal(doc.comments.length, 2); + doc.comments.forEach(function(d) { + assert.equal(d._id, undefined); + assert.equal(Object.keys(d._doc).indexOf('_id'), -1); + assert.ok(d.title.length); + assert.ok(d.body.length); + assert.equal(typeof d._doc.__v, 'number'); + }); }); it('with lean', async function() {