Progress percentage

Hello There,

I need to calculate student progress in percentage. Let’s say there are 10 courses that they need to complete and so far they finished 5. I need to show there progress in percentage.
I have a collection studentProgress, which has an array field student.
Student:Array
{“courseId”:
“courseName”:“Social”,
“status”:“completed”
“score”:50
},
{
{“courseId”:
“courseName”:“Math”,
“status”:“completed”
“score”:80
},
Something like above. I need to show this gauge chart. First I added new fields by calculating Total Courses($size:“$student) and then size of the score Total Completed($size:”$student.score").
Individually they are giving me right answers, but when I put them all together like
{$multiply:
[{ $divide:
[“$TotalCompleted”,“$TotalCourses”] },
100
]
}
It isn’t giving me the right answer. I feel like there is something wrong with calculating Total Courses field.

Would someone please help me with this.
Thanks in advance.
Sunita

Hello, @sunita_kodali !

I can help you to resolve your issue, but first - read the post about Formatting code and log snippets in posts. Remember: the better you explain your problem, provide examples and format your code in the posts - more people in the forum would want to help you :wink:

Ok, let’s create test collection with sample documents that would be close to your situation:

db.studentProgress.insertMany([
  {
    studentId: 'S1',
    courses: [
      {
        courseId: 'C1',
        courseName: 'Social',
        status: 'completed',
        score: 50
      },
      {
        courseId: 'C2',
        courseName: 'Math',
        status: 'completed',
        score: 100
      },
      {
        courseId: 'C3',
        courseName: 'Geography',
        status: 'completed',
        score: 80
      },
      {
        courseId: 'C4',
        courseName: 'Literature',
        status: 'enrolled',
        score: null
      },
      {
        courseId: 'C5',
        courseName: 'Spanish',
        status: 'enrolled',
        score: null
      },
    ],
  },
  {
    studentId: 'S2',
    courses: [
      {
        courseId: 'C1',
        courseName: 'Social',
        status: 'completed',
        score: 95
      },
      {
        courseId: 'C2',
        courseName: 'Math',
        status: 'enrolled',
        score: null
      },
    ],
  }
]);

We can easily calculate each student progress with the following aggregation pipeline:

db.studentProgress.aggregate([
  {
    $addFields: {
      totalCoursesEnrolled: {
        $size: '$courses'
      },
      totalCoursesCompleted: {
        $size: {
          $filter: {
            input: '$courses',
            cond: {
              $eq: ['$$this.status', 'completed']
            }
          }
        }
      }
    }
  },
  {
    $addFields: {
      percentageOfCompletedCourses: {
        $multiply: [
          { $divide: ['$totalCoursesCompleted', '$totalCoursesEnrolled'] },
          100
        ]

      }
    }
  },
  // clean results
  {
    $project: {
      _id: false,
      courses: false,
    }
  }
]);

Output:

[
  {
    studentId: 'S1',
    totalCoursesEnrolled: 5,
    totalCoursesCompleted: 3,
    percentageOfCompletedCourses: 60
  },
  {
    studentId: 'S2',
    totalCoursesEnrolled: 2,
    totalCoursesCompleted: 1,
    percentageOfCompletedCourses: 50
  }
]

Notice: you can not calculate fields and reuse them within the same stage. That is why I needed to use stage $addFields two times :wink:

1 Like

got it. Thank you for detailed explanation.