I want to get the size of array in the model:
const UserSchema = mongoose.Schema(
{
username: { type: String, lowercase: true, required: true },
items: { type: [mongoose.Types.ObjectId], default: [] },
},
{
toJSON : {
virtuals : true
},
timestamps: true,
}
);
UserSchema.virtual("itemsCount").get(function () {
return this.items.length;
});
module.exports = {
UserModel: mongoose.model("user", UserSchema ),
};
const ProductSchema = mongoose.Schema(
{
name: { type: String, required: true },
owner: { type: mongoose.Types.ObjectId,required: true, ref:"user"
},
},
{
toJSON : {
virtuals : true
},
timestamps: true,
}
);
module.exports = {
ProductModel: mongoose.model("product", ProductSchema ),
};
But I want to hide items in the output whenever I try to use projection it gives an error:
Cannot read properties of undefined (reading 'length')
const newPosts = await ProductModel.find({}).populate([{ path: "owner", select: { itemsCount: 0 }}]);
if I don't use select
it works:
const newPosts = await ProductModel.find({}).populate([{ path: "owner" }}]);
But I don't want to show items
filed in output
CodePudding user response:
You can use aggregation pipeline for this:
ProductModel.aggregate([
{
"$lookup": {
"from": "users",
"localField": "user",
"foreignField": "_id",
"as": "users"
}
},
{
"$unwind": "$users"
},
{
"$project": {
_id: "$_id",
name: "$name",
"users": {
itemsCount: {
$size: "$users.items"
}
}
}
}
])
Read more about $lookup, $unwind, $project to understand.
Here is the Mongodb playground to see the results: https://mongoplayground.net/p/R0ZQiV8I-YM