I have an aggregate that I’ve built which does what i need it to do and counts how many of each rating (1-5) a user has been given. They can receive a rating from two distinct parties. which are presented and calculated separately then with a total avg as well.
(yes, I have probably over complicated it, but it works currently. Hopefully, it doesn’t run into issues in the future with size)
What I’d like to try and do is add a 0 count to the ratings not found.
this is an example of the output.
in supervisor_counts you can see the user recieved 53 ratings of 1 and 1 rating of 5.
Id like it to be able to also show 0 for the possible ratings of 2, 3 and 4.
{
"_id": "string",
"supervisor_rating_avg": 1.0740740740740742,
"supervisor_rating_count": 58,
"supervisor_counts": [
{
"rating": 5,
"count": 1
},
{
"rating": 1,
"count": 53
}
],
"venue_manager_rating_avg": 1.9814814814814814,
"venue_manager_rating_count": 107,
"venue_manager_counts": [
{
"rating": 2,
"count": 53
},
{
"rating": 1,
"count": 1
}
],
"totalAvg": 1.5277777777777777
}
This is the aggregate
[
{
'$unwind': {
'path': '$tasks'
}
}, {
'$facet': {
'vmratings': [
{
'$group': {
'_id': {
'resource': '$tasks.resource.uuid',
'rating': '$tasks.venue_manager_assessment.rating'
},
'count': {
'$sum': 1
},
'vmratingavg': {
'$avg': '$tasks.venue_manager_assessment.rating'
}
}
}, {
'$group': {
'_id': '$_id.resource',
'vmcounts': {
'$push': {
'rating': '$_id.rating',
'count': '$count'
}
}
}
}
],
'sratings': [
{
'$group': {
'_id': {
'resource': '$tasks.resource.uuid',
'rating': '$tasks.supervisor_assessment.rating'
},
'count': {
'$sum': 1
}
}
}, {
'$group': {
'_id': '$_id.resource',
'scounts': {
'$push': {
'rating': '$_id.rating',
'count': '$count'
}
}
}
}
],
'totalAvg': [
{
'$group': {
'_id': '$tasks.resource.uuid',
'vmratingavg': {
'$avg': '$tasks.venue_manager_assessment.rating'
},
'sratingavg': {
'$avg': '$tasks.supervisor_assessment.rating'
},
'sratingcount': {
'$sum': '$tasks.supervisor_assessment.rating'
},
'vmratingcount': {
'$sum': '$tasks.venue_manager_assessment.rating'
}
}
}
]
}
}, {
'$project': {
'result': {
'$map': {
'input': {
'$range': [
0, {
'$size': '$vmratings'
}
]
},
'as': 'x',
'in': {
'$let': {
'vars': {
'id': {
'$arrayElemAt': [
'$vmratings._id', '$$x'
]
}
},
'in': {
'_id': '$$id',
'vmratings': {
'$first': {
'$filter': {
'input': '$vmratings',
'as': 'q',
'cond': {
'$eq': [
'$$q._id', '$$id'
]
}
}
}
},
'sratings': {
'$first': {
'$filter': {
'input': '$sratings',
'as': 'q',
'cond': {
'$eq': [
'$$q._id', '$$id'
]
}
}
}
},
'totalAvg': {
'$first': {
'$filter': {
'input': '$totalAvg',
'as': 'q',
'cond': {
'$eq': [
'$$q._id', '$$id'
]
}
}
}
}
}
}
}
}
}
}
}, {
'$unwind': {
'path': '$result'
}
}, {
'$replaceWith': {
'$mergeObjects': [
'$result.sratings', '$result.totalAvg', '$result.vmratings'
]
}
}, {
'$project': {
'_id': '$_id',
'supervisor_rating_avg': '$sratingavg',
'supervisor_rating_count': '$sratingcount',
'supervisor_counts': '$scounts',
'venue_manager_rating_avg': '$vmratingavg',
'venue_manager_rating_count': '$vmratingcount',
'venue_manager_counts': '$vmcounts',
'totalAvg': {
'$divide': [
{
'$sum': [
'$vmratingavg', '$sratingavg'
]
}, 2
]
}
}
}
]
any suggestions on simplifying are also welcome