My product document looks thus:
{
"_id": {
"$oid": "60999af1160b0eebed51f203"
},
"name": "Olive Skin care On1",
"business": {
"$oid": "609fa1d25adc157a33c59098"
},
"ratings": [{
"_id": {
"$oid": "60bdb541d6212ec44e62273c"
},
"user": {
"$oid": "5fdce4bd75dbe4864fcd5001"
},
"rating": 5
}]
}
I have this mongoose query to get product details alongside the product rating. Some products have ratings field while others do not. When I make a query as shown here, it returns a response as expected with calculated average rating. The response looks thus:
[
{
"_id": "609a657f2bf43c290fb22df8",
"name": "Olive babay Oil",
"business": "6079ed084d9ab0c3171317ea",
"averageRating": 5
}
]
Here is the query:
const productArray = await Product.aggregate([
{
$match: {
_id: mongooseProductId,
},
},
{ $unwind: "$ratings" },
{
$project: {
averageRating: { $avg: "$ratings.rating" },
name: 1,
business: 1,
},
},
]);
However if the same product above is modified by removing the ratings field, the query below will return an empty array. How do I write my query to ensure that whether the ratings field exists or not, I do not get an empty array provided that the matching criteria is met.
Meaning that I can get an expected response like this when the ratings field doesn't exist on my product document:
[
{
"_id": "609a657f2bf43c290fb22df8",
"name": "Olive babay Oil",
"business": "6079ed084d9ab0c3171317ea",
"averageRating": null
}
]
And this when the rating field exists:
[
{
"_id": "609a657f2bf43c290fb22df8",
"name": "Olive babay Oil",
"business": "6079ed084d9ab0c3171317ea",
"averageRating": 5
}
]
Based on @turivishal's comment. The query below solved the problem.
const productArray = await Product.aggregate([
{
$match: {
_id: mongooseProductId,
},
},
{ $unwind:{ path: "$ratings", preserveNullAndEmptyArrays: true } },
{
$project: {
averageRating: { $avg: "$ratings.rating" },
name: 1,
business: 1,
},
},
]);