Aggregation Framework
Aggregation Framework - RETRIEVING DATA EFFICIENTLY AND IN A STRUCTURED WAY
https://www.mongodb.com/docs/manual/aggregation/
db.orders.aggregate( [{   // Stage 1: FILTER   $match: { size: "medium" }},{   // Stage 2: GROUP remaining documents by pizza name and calculate total quantity   $group: { _id: "$name", totalQuantity: { $sum: "$quantity" } }}] )The $match stage:
- Filters the pizza order documents to pizzas with a size of medium.
 - Passes the remaining documents to the $group stage. The $group stage:
 - Groups the remaining documents by pizza name.
 - Uses $sum to calculate the total order quantity for each pizza name. The total is stored in the totalQuantity field returned by the aggregation pipeline.
 
//Sacar las personas female agrupadas por estadodb.persons.aggregate([    { $match: { gender: 'female' } },    { $group: { _id: { state: "$location.state" }, totalPersons: { $sum: 1 } } },        // Le asignamos un DOCUMENT al ID,        // esto se interpretará de una manera especial que permitira agrupar los campos        // totalPersons es una key        // sumamos 1 por cada uno que encuentre    { $sort: { totalPersons: -1 } }        // solo podemos ordernar TRAS tener totalPersons]).pretty();db.persons.aggregate([{  $project: {    _id: 0,    name: 1, // le tenemos que pasar los elementos que van a ser usados en el siguiente STAGE (project)    email: 1,    //birthdate: { $convert: { input: '$dob.date', to: 'date' } },    birthdate: { $toDate: '$dob.date' },    age: "$dob.age",    location: {      type: 'Point',      coordinates: [        {          $convert: { // Parsing de datos ya que si no se pasan como string            input: '$location.coordinates.longitude',            to: 'double',            onError: 0.0,            onNull: 0.0          }        },        {          $convert: {            input: '$location.coordinates.latitude',            to: 'double',            onError: 0.0,            onNull: 0.0          }        }      ]    }  }},{  $project: {    gender: 1,    email: 1,    location: 1, // este es el valor de la localización de arriba    birthdate: 1,    age: 1,    fullName: {      $concat: [        { $toUpper: { $substrCP: ['$name.first', 0, 1] } },        {          $substrCP: [            '$name.first',            1,            { $subtract: [{ $strLenCP: '$name.first' }, 1] }          ]        },        ' ',        { $toUpper: { $substrCP: ['$name.last', 0, 1] } },        {          $substrCP: [            '$name.last',            1,            { $subtract: [{ $strLenCP: '$name.last' }, 1] }          ]        }      ]    }  }},{ $group: { _id: { birthYear: { $isoWeekYear: "$birthdate" } }, numPersons: { $sum: 1 } } },{ $sort: { numPersons: -1 } }]).pretty();db.friends.aggregate([    { $unwind: "$hobbies" }, // divide las colecciones padre del array y si tiene dos elementos    // crea dos elementos cada uno con un atriburo diferente    //{ $group: { _id: { age: "$age" }, allHobbies: { $push: "$hobbies" } } }    // introduce un elemento nuevo para cada entrada de elemento, pero como elementos en conjunto, no por separado    { $group: { _id: { age: "$age" }, allHobbies: { $addToSet: "$hobbies" } } }    // mete los valores pero evita valores repetidos  ]).pretty();db.friends.aggregate([    { $project: { _id: 0, examScore: { $slice: ["$examScores", 2, 1] } } }  ]).pretty();// length of array (numero de exámenes)db.friends.aggregate([    { $project: { _id: 0, numScores: { $size: "$examScores" } } }  ]).pretty();// Exámenes con nota má sde 60db.friends.aggregate([    {      $project: {        _id: 0,        scores: { $filter: { input: '$examScores', as: 'sc', cond: { $gt: ["$$sc.score", 60] } } }        // tiene $$ por que filter necesita la variable temporal para realizar la itenrancia, y se escribe así      }    }  ]).pretty();// La mayor puntuación para cada personadb.friends.aggregate([    { $unwind: "$examScores" },    { $project: { _id: 1, name: 1, age: 1, score: "$examScores.score" } },    { $sort: { score: -1 } },    { $group: { _id: "$_id", name: { $first: "$name" }, maxScore: { $max: "$score" } } },    { $sort: { maxScore: -1 } }  ]).pretty();// Agrupar personas por edad
db.persons  .aggregate([    {      $bucket: { // Agrupar los datos en bloques para hacer cosas con los datos        groupBy: '$dob.age',        boundaries: [18, 30, 40, 50, 60, 120], // Categorías        output: {          numPersons: { $sum: 1 },          averageAge: { $avg: '$dob.age' }        }      }    }  ])  .pretty();
db.persons.aggregate([    {      $bucketAuto: { // De manera automática, devuelve un array con los tramos        groupBy: '$dob.age',        buckets: 5,        output: {          numPersons: { $sum: 1 },          averageAge: { $avg: '$dob.age' }        }      }    }  ]).pretty();// Paginationdb.persons.aggregate([    { $match: { gender: "male" } },    { $project: { _id: 0, gender: 1, name: { $concat: ["$name.first", " ", "$name.last"] }, birthdate: { $toDate: "$dob.date" } } },    { $sort: { birthdate: 1 } },    { $skip: 10 },    { $limit: 10 } // limita el número de entradas que queremos ver  ]).pretty();MongoDB actually tries its best to optimize your Aggregation Pipelines without interfering with your logic. Learn more about the default optimizations MongoDB performs in this article: https://docs.mongodb.com/manual/core/aggregation-pipeline-optimization/
{ $out: "transformedPersons" } // Puedes añadirlo al final de un aggregate para crear una colección nueva con la respuesta
// creamos el indice para poder hacer los cálculosdb.transformedPersons.createIndex({location: "2dsphere"})
//db.transformedPersons.aggregate([    {      $geoNear: { // Encuenta elementos en la coleccion que están cerca de nuestro punto        near: {          type: 'Point',          coordinates: [-18.4, -42.8]        },        maxDistance: 1000000,        num: 10,        query: { age: { $gt: 30 } },        distanceField: "distance"      }    }  ]).pretty();Helpful Articles/ Docs:
- Official Aggregation Framework Docs: https://docs.mongodb.com/manual/core/aggregation-pipeline/
 - Learn more about $cond: https://docs.mongodb.com/manual/reference/operator/aggregation/cond/