hat
hat

Reputation: 63

How to iterate an object/array in MongoDB

I have data input that looks something similar to

{
    "someone": {
        "semesters":[
            {
                "semester": "Fall",
                "grades" : [
                    {
                        "exam" : "Midterm 1",
                        "sections" :[
                            {
                                "section" : "First Section",
                                "grade" : 30
                            },
                            {
                                "section" : "Second Section",
                                "grade" : 40
                            },
                            {
                                "section" : "Third Section",
                                "grade" : 50
                            }
                        ]
                    },
                    {
                        "exam" : "Midterm 2",
                        "sections" :[
                            {
                                "section" : "First Section",
                                "grade" : 12
                            },
                            {
                                "section" : "Second Section",
                                "grade" : 21
                            },
                            {
                                "section" : "Third Section",
                                "grade" : 56
                            }
                        ]
                    }
                ]
            }
        ]
    },
    "someone_else": {
        "semesters":[
            {
                "semester": "Fall",
                "grades" : [
                    {
                        "exam" : "Midterm 1",
                        "sections" :[
                            {
                                "section" : "First Section",
                                "grade" : 34
                            },
                            {
                                "section" : "Second Section",
                                "grade" : 3
                            },
                            {
                                "section" : "Third Section",
                                "grade" : 51
                            }
                        ]
                    },
                    {
                        "exam" : "Midterm 2",
                        "sections" :[
                            {
                                "section" : "First Section",
                                "grade" : 16
                            },
                            {
                                "section" : "Second Section",
                                "grade" : 80
                            },
                            {
                                "section" : "Third Section",
                                "grade" : 95
                            }
                        ]
                    }
                ]
            }
        ]
    }
}

I was wondering if there was a way to iterate through all the grades from multiple documents and make an output list that is sorted for all grades in the system. The data above should result in something like First Section:

{ name : someone_else, section: First Section, grade : 34 }, 
{ name : someone, section: First Section, grade : 30 }, 
{ name : someone_else, section: First Section, grade : 16 }, 
{ name : someone, section: First Section, grade : 12 }, 

I want to be able to change the section section and be able to find data for the highest grade in each specific sorted to lowest.

Upvotes: 1

Views: 562

Answers (1)

Tom Slabbaert
Tom Slabbaert

Reputation: 22296

This is actually quite simple, we just need to convert the grades object to an array using $objectToArray, then we can project and sort the into the required output, like so:

db.collection.aggregate([
  {
    $unwind: "$grades"
  },
  {
    $addFields: {
      grades: {
        "$objectToArray": "$grades"
      }
    }
  },
  {
    $unwind: "$grades"
  },
  {
    $project: {
      name: 1,
      grade: "$grades.v"
    }
  },
  {
    $sort: {
      grade: -1
    }
  }
])

Mongo Playground

Upvotes: 1

Related Questions