Home > Software engineering >  Getting aggregate count for nested fields in mongo
Getting aggregate count for nested fields in mongo

Time:12-10

I have a mongo collection mimicking this java class. A student can be taught a number of subjects across campus.

 class Students {
     String studentName;
     Map<String,List<String>> subjectsByCampus;
}

So a structure will look like this

{
 _id: ObjectId("someId"),
 studentName:'student1',
subjectByCampusName:{
 campus1:['subject1','subject2'],
 campus2: ['subject3']
},
_class: 'fqnOfTheEntity'
}

I want to find the count of subjects offered by each campus or be able to query the count of subjects offered by a specific campus. Is there a way to get it through query?

CodePudding user response:

Mentioned in the comments, but the schema here does not appear to be particularly well-suited toward gathering the data requested in the question. For an individual student, this is doable via $size and processing the object (as an array) via $map. For example, if we want your desired out put of campus1:2, campus2:1 for the sample document provided, a pipeline to produce that in a countsByCampus field might look as follows:

[
  {
    "$addFields": {
      "countsByCampus": {
        "$arrayToObject": {
          "$map": {
            "input": {
              "$objectToArray": "$subjectByCampusName"
            },
            "in": {
              "$mergeObjects": [
                "$$this",
                {
                  v: {
                    $size: "$$this.v"
                  }
                }
              ]
            }
          }
        }
      }
    }
  }
]

Playground demonstration here with an output document of:

  {
    "_class": "fqnOfTheEntity",
    "_id": "someId",
    "countsByCampus": {
      "campus1": 2,
      "campus2": 1
    },
    "studentName": "student1",
    "subjectByCampusName": {
      "campus1": [
        "subject1",
        "subject2"
      ],
      "campus2": [
        "subject3"
      ]
    }
  }

Doing that across the entire collection would involve $grouping the results together. This can be done but would be an extremely resource-intensive and likely slow operation.

  • Related