Search code examples
mongodbmongodb-queryaggregation-frameworkpymongonested-documents

how to filter scores from the nested document using (MONGO DB OR PYMONGO).if all the scores of a particular person is greater than 40


[
  {
    "_id": 5,
    "name": "Wilburn Spiess",
    "scores": [
      {
        "score": 44.87186330181261,
        "type": "exam"
      },
      {
        "score": 25.72395114668016,
        "type": "quiz"
      },
      {
        "score": 63.42288310628662,
        "type": "homework"
      }
    ]
  },
  {
    "_id": 6,
    "name": "Jenette Flanders",
    "scores": [
      {
        "score": 37.32285459166097,
        "type": "exam"
      },
      {
        "score": 28.32634976913737,
        "type": "quiz"
      },
      {
        "score": 81.57115318686338,
        "type": "homework"
      }
    ]
  },
  {
    "_id": 7,
    "name": "Salena Olmos",
    "scores": [
      {
        "score": 90.37826509157176,
        "type": "exam"
      },
      {
        "score": 42.48780666956811,
        "type": "quiz"
      },
      {
        "score": 96.52986171633331,
        "type": "homework"
      }
    ]
  }
]

Solution

  • Query1

    • keep a document, if the min score> 40 (all scores > 40)

    Playmongo

    aggregate(
    [{"$match": {"$expr": {"$gt": [{"$min": "$scores.score"}, 40]}}}])
    

    Query2

    • all scores for >40 and <70
    • and change the array to have the type as key as your expected ouput

    Playmongo

    aggregate(
    [{"$match": 
       {"$expr": 
         {"$and": 
           [{"$gt": [{"$min": "$scores.score"}, 40]},
             {"$lt": [{"$max": "$scores.score"}, 70]}]}}},
     {"$set": 
       {"scores": 
         {"$arrayToObject": 
           [{"$map": 
               {"input": "$scores",
                "as": "s",
                "in": {"k": "$$s.type", "v": "$$s.score"}}}]}}},
     {"$replaceRoot": 
       {"newRoot": 
         {"$mergeObjects": [{"name": "$name", "_id": "$_id"}, "$scores"]}}}])