skip to Main Content
{
   name: "use_name",
   grades: [
     {class: "math": grade: 100},
     {class: "english": grade: 90}
   ]
}

How do I write an aggregation pipeline to output:

{
   name: "use_name",
   grades: {class: "math": grade: 100},
   
}

The grades field has been reduced to the element where its grade property is the maximum of all elements.

The requirements, the aggregation pipeline cannot have $unwind or $group because it cannot have a stage where the stage needs to receive all incoming documents before outputting to the next stage, potentially exceeding the 100mb limit. And it must be fast.

2

Answers


  1. Replace $$value in $reduce until you find the max.

    db.collection.aggregate([
      {
        $set: {
          grades: {
            "$reduce": {
              "input": "$grades",
              "initialValue": null,
              "in": {
                "$cond": {
                  "if": {
                    $or: [
                      {
                        $eq: [
                          null,
                          "$$value"
                        ]
                      },
                      {
                        $gt: [
                          "$$this.grade",
                          "$$value.grade"
                        ]
                      }
                    ]
                  },
                  "then": "$$this",
                  "else": "$$value"
                }
              }
            }
          }
        }
      }
    ])
    

    Mongo Playground

    Login or Signup to reply.
  2. I think this one is faster:

    db.collection.aggregate([
      {
        $set: {
          grades: {
            $first: {
              $sortArray: {
                input: "$grades",
                sortBy: { grade: -1 }
              }
            }
          }
        }
      }
    ])
    

    Mongo Playground

    or this one:

    db.collection.aggregate([
      {
        $set: {
          grades: {
            $filter: {
              input: "$grades",
              cond: { $eq: [ "$$this.grade", { $max: "$grades.grade" } ] }
            }
          }
        }
      }
    ])
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search