Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

99
Visualizações
Mongodb find the highest two exams scores

I have a student collection that looks like this: How to find a maximum of two exam scores for every student

[
  {
    "_id" : ObjectId("61868aa03b2fe72b58c891a5"),
    "name" : "Max",
    "examScores" : [ 
        {
            "difficulty" : 4,
            "score" : 57.9
        }, 
        {
            "difficulty" : 6,
            "score" : 62.1
        }, 
        {
            "difficulty" : 3,
            "score" : 88.5
        }
    ]
},

{
    "_id" : ObjectId("61868aa03b2fe72b58c891a6"),
    "name" : "Manu",
    "examScores" : [ 
        {
            "difficulty" : 7,
            "score" : 52.1
        }, 
        {
            "difficulty" : 2,
            "score" : 74.3
        }, 
        {
            "difficulty" : 5,
            "score" : 53.1
        }
    ]
}
]

I want to use aggregation to return the two highest examScores.score like this:

[
 {
  name: "Max",
  maxExams: [88.5, 62.1]
 },
 {
  name: "Manu",
  maxExams: [74.3, 53.1]
 }
]

I am tried the aggregation stage $project and $unwind and $sort but all of them fail to solve my problem

about 4 years ago · Juan Pablo Isaza
2 Respostas
Responde à pergunta

0

Here it is:

 mongos> db.s.aggregate([ 
        {$unwind:"$examScores"},
        {$sort:{"name":1,"examScores.score":-1}},
        {$group:{ _id:"$name" ,Scores:{$push:"$examScores.score"}  }}, 
        {$project:{_id:0,name:"$_id",maxExam:{$slice:["$Scores",2]}}}
        ])

       { "name" : "Manu", "maxExam" : [ 74.3, 53.1 ] }
       { "name" : "Max", "maxExam" : [ 88.5, 62.1 ] }
mongos> 

Explained:

  1. Unwind the scores so you can sort them later.
  2. Sort by name and scores max to min
  3. group the scores in new array Scores
  4. project the name & maxExam ( sliced first 2 from Scores )
about 4 years ago · Juan Pablo Isaza Relatório

0

Query

  • you can reduce and keep only the max 2 scores
  • starts with [-1,-1] if score >= first member add left(old right will be removed), else if score >= second member add right(old right will be removed), else do nothing
  • if you wanted more than 2-3
    • if MongoDB 5 you $setWindowFields could be used
    • else unwind group slice 2 solution

*here you dont need unwind/group/sort etc because only 2.

PlayMongo

aggregate(
[{"$project": 
    {"_id": 0,
      "name": 1,
      "maxExams": 
      {"$reduce": 
        {"input": "$examScores",
          "initialValue": [-1, -1],
          "in": 
          {"$switch": 
            {"branches": 
              [{"case": 
                  {"$gte": ["$$this.score", {"$arrayElemAt": ["$$value", 0]}]},
                  "then": 
                  {"$concatArrays": 
                    [["$$this.score"], [{"$arrayElemAt": ["$$value", 0]}]]}},
                {"case": 
                  {"$gte": ["$$this.score", {"$arrayElemAt": ["$$value", 1]}]},
                  "then": 
                  {"$concatArrays": 
                    [[{"$arrayElemAt": ["$$value", 0]}], ["$$this.score"]]}}],
              "default": "$$value"}}}}}}])
about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda