I have a problem getting the scores from all students who answered questions in a test using the mongodb aggregation pipeline approach
My aggregation pipeline gives an array of objects , which is made up of every students answer to the test questions.
The pipeline would be something like the one below, my example is simplified from my actual problem. Basically I group and push each questions array for each user into scores field. Then I use reduce to flatten the scores field
{ $group: {
_id: {},
scores: { $push: "$questions" }
} },
{ $addFields: {
testScores: {
$reduce: {
input: "$scores",
initialValue: [ ],
in: { $concatArrays: [ "$$value", "$$this" ] }
}
}
} }
The result would look something like:
testScores: [
{ id: 'questionOne' score: 1 },
{ id: 'questionOne', score: 3 },
{ id: 'questionOne', score: 8 },
{ id: 'questionOne' score: 2 },
....
{ id: 'questionFifty' score: 1 },
{ id: 'questionFifty', score: 3 },
{ id: 'questionFifty', score: 8 },
{ id: 'questionFifty' score: 2 }
]
My question is how do I get the average score for all scores for 'questionOne' and all the other questions ? I cannot unwind my array as I have a large number of tests and it seems mongoDb cannot unwind a sufficient number without returning null for the aggregation result.
In JavaScript I'd use reduce but as I understand it, mongodb allows use of vars outside the reduce function but as far as I understand you cannot modify the reduce function so something similar to the function below would not be possible.
myArray.reduce((acc, next){
if(acc[next.id]}{
acc[next.id].score += next.score
acc[next.id].count+= 1
acc[next].avg = acc[next.id].score/acc[next.id].count
}else{
acc[next.id].score = next.score
acc[next.id].count = 1
}
return acc
},{} }
Thanks for any pointers