Search code examples
mongodbmongodb-querynosqlaggregation-frameworkmongodb-indexes

How to transform an array field into a value equaling its maximum?


{
   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.


Solution

  • 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" } ] }
            }
          }
        }
      }
    ])