I have to rename the name of the field when using populate.
const CategorySchema = new Schema(
{
name: {
type: String,
unique: true
},
featured: {
type: Boolean,
default: true
},
image: String,
active: {
type: Boolean,
default: true
},
subCategoryIds: [{ type: Schema.Types.ObjectId, ref: 'SubCategory' }]
},
{
timestamps: true
}
);
export default mongoose.model('Category', CategorySchema);
This is my Category Schema.
And here is my SubCategory Schema
const SubCategory = new Schema(
{
name: {
type: String,
unique: true
},
active: {
type: Boolean,
default: true
},
categoryId: { type: Schema.Types.ObjectId, ref: 'Category' },
productIds: [{ type: Schema.Types.ObjectId, ref: 'Product' }]
},
{
timestamps: true
}
);
SubCategory.virtual('category', {
ref: 'Category',
localField: 'categoryId',
foreignField: '_id'
});
export default mongoose.model('SubCategory', SubCategory);
And here I have a filed categoryId
, when using populate, I want it to be 'category', So I used virtual
to create 'category`.
and implemented this
const subCategories = await SubCategory.find({}).populate('category');
But unfortunately it isn't working, It returns the normal subCategory
object and there is no category present.
Am I missing something?
Why dont you use Mongodb
aggregation pipeline, instead of using mongoose virtuals
, You can use $lookup
and change catergoryId
to category while populating.
Try this:
const subCategories = await SubCategory.aggregate([{
$lookup : {
from : "categories",
localField : "categoryId",
foreginField : "_id",
as : "category"
},{
$unwind : "$category"
}])
localField
says which field to populate, from
tells monogdb which collection to populate from, foreignField
tells mongodb which field to match it for population, and as
is used for the field in which result will be stored,
$unwind
is used in the next stage, because $lookup
returns an array, we need to convert it to category object
Read Mongodb $lookup documentation for more info.