-
-
Notifications
You must be signed in to change notification settings - Fork 3.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unexpected population of virtual with match() function in an embedded subdocument array #14494
Closed
2 tasks done
Labels
confirmed-bug
We've confirmed this is a bug in Mongoose and will fix it.
Milestone
Comments
vkarpov15
added
the
has repro script
There is a repro script, the Mongoose devs need to confirm that it reproduces the issue
label
Apr 4, 2024
IslandRhythms
added
confirmed-bug
We've confirmed this is a bug in Mongoose and will fix it.
and removed
has repro script
There is a repro script, the Mongoose devs need to confirm that it reproduces the issue
labels
Apr 5, 2024
const mongoose = require('mongoose');
const gradeSchema = new mongoose.Schema({
studentId: mongoose.Types.ObjectId,
classId: mongoose.Types.ObjectId,
grade: String,
});
const Grade = mongoose.model('Grade', 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 = mongoose.model('Class', classSchema);
async function run() {
await mongoose.connect('mongodb://localhost:27017');
await mongoose.connection.dropDatabase();
const newClass = await Class.create({
name: 'History',
students: [{ name: 'Henry' }, { name: 'Robert' }],
});
const studentRobert = newClass.students.find(
({ name }) => name === 'Robert'
);
await Grade.insertMany([
{
studentId: studentRobert._id,
classId: newClass._id,
grade: 'B',
},
]);
const latestClass = await Class.findOne({ name: 'History' })
.populate('students.grade')
.select('-__v')
.exec();
// Robert's grade is populated in Henry's student object
console.log(
JSON.stringify(latestClass.toJSON({ virtuals: true }).students, null, 4)
);
}
run(); |
vkarpov15
added a commit
that referenced
this issue
Apr 11, 2024
fix(populate): avoid match function filtering out `null` values in populate result
This was referenced May 21, 2024
This was referenced Jun 7, 2024
This was referenced Jun 9, 2024
This was referenced Jun 12, 2024
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Prerequisites
Mongoose version
8.2.1
Node.js version
20.5.1
MongoDB server version
6.3.0
Typescript version (if applicable)
No response
Description
Populating a virtual with a match() function in an embedded subdocument array inserts the populated document in the wrong array element.
In the example below, I have defined a
Class
model with an array ofstudents
where each element is a nested schemastudentSchema
. I have defined another modelGrade
which represents a student's grade in a class. The student schema has agrade
virtual representing the student's grade in the class (parent document).When populating the
grade
virtual, grades in the class are assigned to the incorrect student subdocument unless every student has a grade in the class.Steps to Reproduce
The following code shows the unexpected behavior of populating a virtual with a match() function on an embedded subdocument.
Output
Expected Behavior
The text was updated successfully, but these errors were encountered: