Every time user rates some post from 1 to 5, that number is written (as property value) with userId as property name.
"starRatingByUser" : {
"iZxSjCduTjfCQbmf9" : 3,
"LvBr6a427ofuvXFMp" : 4,
"gfhfhfh98rtgfXFft" : 5
}
Is it possible to insert (update) new field ("starRatingAverage") with average of all ratings every time users add or updates rating?
Example:
"starRatingAverage": 4,
"starRatingByUser" : {
"iZxSjCduTjfCQbmf9" : 3,
"LvBr6a427ofuvXFMp" : 4,
"gfhfhfh98rtgfXFft" : 5
}
I have this method:
Recipes.update(
{ _id: recipeId },
{ $set: { ["starRatingByUser." + this.userId]: star }}
)
[example image] : https://i.sstatic.net/CuWbR.png
There is an option to update using aggregation in mongodb. Update-documents-with-aggregation-pipeline
In aggregation
$objectToArray
to calculate the total$size
and calculate the total using $reduce
$project
to remove unwanted fieldsthe script is
db.colelction.updateOne(
{_id:1},
[
{
$addFields: {
stu: {
"$objectToArray": "$starRatingByUser"
}
}
},
{
$addFields: {
size: {
$size: "$stu"
},
total: {
$reduce: {
input: "$stu",
initialValue: 0,
in: {
$add: [
"$$this.v",
"$$value"
]
}
}
}
}
},
{
"$project": {
starRatingByAverage: {
"$divide": [
"$total",
"$size"
]
},
starRatingByUser: 1
}
}
])
This query is checked and working fine