Skip to content

Commit

Permalink
fix(populate): avoid match function filtering out null values in po…
Browse files Browse the repository at this point in the history
…pulate result

Fix #14494
  • Loading branch information
vkarpov15 committed Apr 10, 2024
1 parent 4ea42d2 commit ae37362
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 2 deletions.
4 changes: 2 additions & 2 deletions lib/helpers/populate/assignVals.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ module.exports = function assignVals(o) {
valueToSet = numDocs(rawIds[i]);
} else if (Array.isArray(o.match)) {
valueToSet = Array.isArray(rawIds[i]) ?
rawIds[i].filter(sift(o.match[i])) :
[rawIds[i]].filter(sift(o.match[i]))[0];
rawIds[i].filter(v => v == null || sift(o.match[i])(v)) :
[rawIds[i]].filter(v => v == null || sift(o.match[i])(v))[0];
} else {
valueToSet = rawIds[i];
}
Expand Down
53 changes: 53 additions & 0 deletions test/model.populate.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10968,4 +10968,57 @@ describe('model: populate:', function() {
assert.equal(res.children[0].subdoc.name, 'A');
assert.equal(res.children[1].subdoc.name, 'B');
});

it('avoids filtering out `null` values when applying match function (gh-14494)', async function() {
const gradeSchema = new mongoose.Schema({
studentId: mongoose.Types.ObjectId,
classId: mongoose.Types.ObjectId,
grade: String
});

const Grade = db.model('Test', gradeSchema);

const studentSchema = new mongoose.Schema({
name: String
});

studentSchema.virtual('grade', {
ref: Grade,
localField: '_id',
foreignField: 'studentId',
match: (doc) => ({
classId: doc._id
}),
justOne: true
});

const classSchema = new mongoose.Schema({
name: String,
students: [studentSchema]
});

const Class = db.model('Test2', classSchema);

const newClass = await Class.create({
name: 'History',
students: [{ name: 'Henry' }, { name: 'Robert' }]
});

const studentRobert = newClass.students.find(
({ name }) => name === 'Robert'
);

await Grade.create({
studentId: studentRobert._id,
classId: newClass._id,
grade: 'B'
});

const latestClass = await Class.findOne({ name: 'History' }).populate('students.grade');

assert.equal(latestClass.students[0].name, 'Henry');
assert.equal(latestClass.students[0].grade, null);
assert.equal(latestClass.students[1].name, 'Robert');
assert.equal(latestClass.students[1].grade.grade, 'B');
});
});

0 comments on commit ae37362

Please sign in to comment.