Cómo agrupar datos con $group en MongoDB

Resumen

El operador $group de MongoDB Aggregation Framework te permite agrupar documentos por un campo común y aplicar operaciones de acumulación sobre ellos, algo que el lenguaje estándar MongoDB Query Language no puede hacer por sí solo. Es una herramienta clave si trabajas con análisis de datos, reportes o segmentación de información dentro de colecciones grandes como las de Airbnb.

¿Qué hace el operador group en MongoDB?

El reto de esta práctica es claro: encontrar la propiedad más barata y la más cara dentro de cada tipo de propiedad (departamentos, casas, etc.) en Estados Unidos. Para resolverlo, necesitas combinar tres etapas dentro de un pipeline de agregación.

¿Qué es el operador $group? Es un operador de MongoDB Aggregation Framework que agrupa documentos según un campo común y permite aplicar acumuladores como $first, $last, $sum o $avg sobre cada grupo.

¿Cómo se construye el pipeline paso a paso?

La consulta se arma en MongoDB Compass desde la pestaña aggregation, en modo texto. El orden importa, porque cada etapa recibe la salida de la anterior.

  1. $match filtra solo las propiedades de Estados Unidos usando address.country_code.
  2. $sort ordena los documentos primero por property_type y luego por price. Este truco es lo que después permite que $first y $last devuelvan el más barato y el más caro.
  3. $group agrupa por tipo de propiedad y aplica los acumuladores.

Cada etapa va separada por coma y respeta sintaxis JSON estricta [02:15].

¿Cómo usar $first y $last para encontrar mínimos y máximos?

Dentro de $group, el campo _id define el ancla de agrupación. En este caso, _id: "$property_type" indica que MongoDB debe crear un grupo por cada tipo de propiedad.

Luego defines campos personalizados con acumuladores. Aquí entra la parte interesante: como ya ordenaste por precio ascendente, el primer documento de cada grupo es el más barato y el último es el más caro.

{ $group: { _id: "$property_type", masBajo: { $first: { nombre: "$name", precio: "$price", direccion: "$address" } }, masAlto: { $last: { nombre: "$name", precio: "$price", direccion: "$address" } } } }

El acumulador $first toma el primer elemento del grupo ordenado y $last toma el último. Así, en una sola etapa, obtienes ambos extremos del rango de precios [04:30].

¿Qué errores son comunes al escribir un $group?

Durante la práctica aparecen dos errores muy típicos que vale la pena tener identificados:

  • Usar nombres de campo en español cuando la colección los tiene en inglés. Escribir precio en lugar de $price rompe la consulta porque ese campo no existe en Airbnb.
  • Olvidar envolver cada acumulador dentro de su propio objeto, lo que genera errores de sintaxis JSON.
  • Confundir las etiquetas: si copias y pegas el bloque de masBajo para crear masAlto, debes renombrar la clave, o terminarás con dos campos que dicen lo mismo pero contienen datos distintos.

¿Por qué $group necesita un campo _id? Porque ese campo le dice a MongoDB sobre qué propiedad agrupar los documentos. Sin _id, no hay agrupación posible.

¿Por qué $group no modifica la base de datos original?

Una de las grandes ventajas del Aggregation Framework es que todo el procesamiento ocurre dentro del pipeline, no sobre los documentos guardados. Tu colección original de Airbnb permanece intacta, y los resultados solo existen como salida temporal de la consulta.

Esto significa que puedes experimentar con distintas agrupaciones, acumuladores y combinaciones sin miedo a alterar los datos. Es ideal para análisis exploratorio, dashboards y reportes en tiempo real.

El resultado final muestra un documento por cada tipo de propiedad con dos objetos anidados: masBajo con la propiedad más económica y masAlto con la más cara, cada uno con su nombre, precio y dirección [06:45].

¿Qué otros acumuladores puedes explorar?

Más allá de $first y $last, el operador $group admite una familia amplia de acumuladores que vale la pena probar:

  • $sum para sumar valores numéricos dentro del grupo.
  • $avg para calcular promedios, útil en análisis de precios medios.
  • $min y $max para obtener directamente el valor mínimo o máximo sin necesidad de ordenar antes.
  • $push y $addToSet para construir arrays con todos los valores del grupo.

Cada uno responde a una pregunta de negocio distinta, y combinarlos dentro de un mismo $group te permite construir reportes muy completos en una sola consulta.

¿Has probado agrupar por más de un campo a la vez o combinar $group con $project? Cuéntanos en los comentarios qué experimentos te han funcionado mejor.