Virtuals populate match works with object but not with function
A-Ghattas opened this issue · 1 comments
A-Ghattas commented
When I use autopopulate to populate a virtual field that use the match option it works fine when I pass an object but doesn't work when I pass a function.
The bug only appears when I use autopopulate. without the plugin, everything works fine.
const mongoose = require('mongoose');
const mongooseAutoPopulate = require('mongoose-autopopulate');
const id = new mongoose.Types.ObjectId();
const subjectId = new mongoose.Types.ObjectId();
const teacherSchema = new mongoose.Schema({
schoolClass: {type: mongoose.Schema.Types.ObjectId, ref: 'SchoolClass', autopopulate: { maxDepth: 2 },},
schoolSubject: { type: mongoose.Schema.Types.ObjectId, ref: 'SchoolSubject', autopopulate: { maxDepth: 2 },},
},
{
timestamps: true,
toObject: { virtuals: true},
toJSON: { virtuals: true},
selectPopulatedPaths: false
});
const lectureSchema = new mongoose.Schema({
schoolClass: { type: mongoose.Schema.Types.ObjectId, ref: 'SchoolClass', autopopulate: { maxDepth: 2 },},
schoolSubject: { type: mongoose.Schema.Types.ObjectId, ref: 'SchoolSubject', autopopulate: { maxDepth: 2 }, },
}, {
timestamps: true,
toObject: { virtuals: true },
toJSON: { virtuals: true }
});
lectureSchema.virtual('assignedTeacher', {
ref: 'Teacher',
localField: 'schoolClass',
foreignField: 'schoolClass',
autopopulate: { maxDepth: 2 },
match: (lecture) => ({
schoolSubject: lecture.schoolSubject
}),
justOne: true
});
// If I replace the code above with this, it works fine
// lectureSchema.virtual('assignedTeacher', {
// ref: 'Teacher',
// localField: 'schoolClass',
// foreignField: 'schoolClass',
// autopopulate: { maxDepth: 2 },
// match: {
// schoolSubject: subjectId
// },
// justOne: true
// });
teacherSchema.plugin(mongooseAutoPopulate);
lectureSchema.plugin(mongooseAutoPopulate);
const classSchema = new mongoose.Schema({
name: String
});
const subjectSchema = new mongoose.Schema({
naem: String
});
const Teacher = mongoose.model('Teacher', teacherSchema);
const Lecture = mongoose.model('Lecture', lectureSchema);
const SchoolClass = mongoose.model('SchoolClass', classSchema);
const SchoolSubject = mongoose.model('SchoolSubject', subjectSchema);
async function run() {
await mongoose.connect('mongodb://127.0.0.1:27017/test-mongoose-bug');
await mongoose.connection.dropDatabase();
await SchoolClass.create({
_id: id,
name: 'MTH-101'
});
const sub = await SchoolSubject.create({
_id: subjectId,
name: 'Math'
});
await Teacher.create({
schoolClass: id,
schoolSubject: sub.id
});
const lecture = await Lecture.create({
schoolClass: id,
schoolSubject: sub.id
});
const data = await Lecture.findOne().populate('assignedTeacher');
console.log(data, '///////', data.assignedTeacher)
}
run();
IslandRhythms commented
const mongoose = require('mongoose');
const mongooseAutoPopulate = require('mongoose-autopopulate');
const id = new mongoose.Types.ObjectId();
const subjectId = new mongoose.Types.ObjectId();
const teacherSchema = new mongoose.Schema({
schoolClass: {type: mongoose.Schema.Types.ObjectId, ref: 'SchoolClass', autopopulate: { maxDepth: 2 },},
schoolSubject: { type: mongoose.Schema.Types.ObjectId, ref: 'SchoolSubject', autopopulate: { maxDepth: 2 },},
},
{
timestamps: true,
toObject: { virtuals: true},
toJSON: { virtuals: true},
selectPopulatedPaths: false
});
const lectureSchema = new mongoose.Schema({
schoolClass: { type: mongoose.Schema.Types.ObjectId, ref: 'SchoolClass', autopopulate: { maxDepth: 2 },},
schoolSubject: { type: mongoose.Schema.Types.ObjectId, ref: 'SchoolSubject', autopopulate: { maxDepth: 2 }, },
}, {
timestamps: true,
toObject: { virtuals: true },
toJSON: { virtuals: true }
});
lectureSchema.virtual('assignedTeacher', {
ref: 'Teacher',
localField: 'schoolClass',
foreignField: 'schoolClass',
autopopulate: { maxDepth: 2 },
match: (lecture) => ({
schoolSubject: lecture.schoolSubject
}),
justOne: true
});
// If I replace the code above with this, it works fine
/*
lectureSchema.virtual('assignedTeacher', {
ref: 'Teacher',
localField: 'schoolClass',
foreignField: 'schoolClass',
autopopulate: { maxDepth: 2 },
match: {
schoolSubject: subjectId
},
justOne: true
});
*/
teacherSchema.plugin(mongooseAutoPopulate);
lectureSchema.plugin(mongooseAutoPopulate);
const classSchema = new mongoose.Schema({
name: String
});
const subjectSchema = new mongoose.Schema({
name: String
});
const Teacher = mongoose.model('Teacher', teacherSchema);
const Lecture = mongoose.model('Lecture', lectureSchema);
const SchoolClass = mongoose.model('SchoolClass', classSchema);
const SchoolSubject = mongoose.model('SchoolSubject', subjectSchema);
async function run() {
await mongoose.connect('mongodb://127.0.0.1:27017/test-mongoose-bug');
await mongoose.connection.dropDatabase();
await SchoolClass.create({
_id: id,
name: 'MTH-101'
});
const sub = await SchoolSubject.create({
_id: subjectId,
name: 'Math'
});
await Teacher.create({
schoolClass: id,
schoolSubject: sub.id
});
const lecture = await Lecture.create({
schoolClass: id,
schoolSubject: sub.id
});
const data = await Lecture.findOne().populate('assignedTeacher');
console.log(data, '///////', data.assignedTeacher)
}
run();