Reputation: 341
I am trying to populate the find results using mongoose. But I am facing an issue.
My data is a list of products and each and every product contains a list of variants. Suppose I have a product named Phone and I have a list of variants named blue, black and green. What I want to do is to return a complete list of products and a sum of stocks.
An Example of product Object is:
{
"name" : "Phone",
"details" : "blaah blaah",
"variants" : [
ObjectId("5e22d3dabb6cc53debc3a4ae"),
ObjectId("5e23629c82aac939fe95c926")
]
}
And an example of variant Object is
[
{
"name" : "blue",
"stocks": 14,
"cost" : 200
},
{
"name" : "black",
"stocks": 9,
"cost" : 202
}
]
Currently I am doing the following
router.get("/fetchProducts", (req, res) => {
Product.find({}).populate("variants")
.then(products => {
res.send(products);
}).catch(err => {
res.send(err)
})
})
But I want to add the stocks of all the variants and append it to the result. Like this
{
"name" : "Phone",
"details" : "blaah blaah",
"variants" : [
{
"name" : "blue",
"stocks": 14,
"cost" : 200
},
{
"name" : "black",
"stocks": 9,
"cost" : 202
}
],
"stocks": 23
}
Upvotes: 0
Views: 485
Reputation: 1922
You can use an aggregation pipeline with a $reduce
operator but before that you have to populate the documents, you can do that with $lookup
which is similar to populate.Here is an example with your data. I haven't tested but I hope it works.
Product.aggregate([{
$lookup: {
from: "variants",
localField: "variant",
foreignField: "_id",
as:"variant"
}
}, {
"$addFields": {
"stocks": {
"$reduce": {
"input": "$variants",
"initialValue": 0,
"in": { "$add" : ["$$value", "$$this.cost"] }
}
}
}
}
]).exec(function(err, data) {
if(err) console.log(err)
console.log(data)
})
Upvotes: 1