[SOLVED] - Get count of true fields which in an subCollection

Hi, I am trying to get count of true’s of isPresent field which in an subCollection with blaze.

StudentYoklamaSchema = new SimpleSchema({
  studentId: SimpleSchema.RegEx.Id,
  isPresent: {
    type: Boolean,
  },
});

AttendanceSchema = new SimpleSchema({
  date: Date,
  groupId: SimpleSchema.RegEx.Id,
  studentList: {
    type: Array,
  },
  "studentList.$": StudentYoklamaSchema,
});

In this sub collection count of isPresent.

Thanks…

Hi, the answer you are looking for is probably here: Count values in array of objects - #4 by Roger_Bieri - Working with Data - MongoDB Developer Community Forums.
You would need to use a $reduce.

I believe your schema would be more efficient if you separated students from the attendance (normalize data in this one-to-many case and denormalize Participations (and embed some of the student data) as below, for the most efficient querying). Ideally you would also create indexes on Participations for attendanceId, groupId and anything else you might use for querying.

Let’s say you have a collection for student data, a collection for students participations and what they participate to.

// Student (user) info
{
_id: .....
name: ...
// etc
}
// Participations (a more relevant name for your context)

{
_id: .....
studentId: ..... // (from above)
attendanceId: ...... // from Attendance collection
courseId: ........ 
courseName: .....
groupId: ...... // you would prefer to write some things in multiple collections to avoid joins/aggregations.
date: .........
isPresent: true // you only save this key if it is true. Missing implies a false.
}
//  Courses
{
_id: .....
name: ......
grade: ..... etc
}
// Attendances
{
_id:.....
courseId: .......
courseName: .....
date: .......
groupId: ......
}

In this way you will be able to use reports, efficient queries, counts and an easy CRUD API.

Example: How many courses in 2022 with over 80% attendance. Students that miss more than 10% of the courses.
In NoSQL Document DBs, it is ok to write the same data multiple times in different collections for efficient querying. For example, it is ok to save a student’s name in Users (Students) and in Participations because it is unlikely that the name will change and anyway you would want to save a student with the name he/she had at that time even if it changes.

In general, it is good to use a mix of normalized and denormalized data models. It happens pretty often to start with a denormalized structure (embedded like in your example) and be forced to adopt a normalized structure later on.

Participations.find({ attendanceId: ....., isPresent: true }).count() // or
Participations.find({ attendanceId: ....., isPresent: { $exists: true } }).count()

If you don’t need to update those objects in the studentList too often and you don’t need complex reports, I think $reduce should do it for you.

1 Like

You need to use aggregation.

$filter the array and then get its $size

1 Like

Thank you very much.