Agrupar Datos de MongoDB

MongoDBBeginner
Practicar Ahora

Introducción

En este laboratorio, aprenderá los fundamentos de la agregación de datos en MongoDB. Se centrará en el uso del pipeline de agregación para agrupar documentos, realizar cálculos sobre datos agrupados y, a continuación, filtrar, ordenar y remodelar los resultados. Estas operaciones son esenciales para el análisis de datos y la generación de informes en MongoDB. Al final de este laboratorio, se sentirá cómodo utilizando el operador $group junto con otras etapas clave de agregación para extraer información significativa de sus datos.

Este es un Guided Lab, que proporciona instrucciones paso a paso para ayudarte a aprender y practicar. Sigue las instrucciones cuidadosamente para completar cada paso y obtener experiencia práctica. Los datos históricos muestran que este es un laboratorio de nivel principiante con una tasa de finalización del 100%. Ha recibido una tasa de reseñas positivas del 91% por parte de los estudiantes.

Agrupar Documentos por un Campo

El primer paso en la agregación de datos suele ser agrupar documentos basándose en un campo común. En este paso, se conectará al shell de MongoDB, creará una nueva base de datos y colección, y luego utilizará el operador $group para agrupar documentos por categoría.

Primero, abra el shell de MongoDB ejecutando el siguiente comando en su terminal:

mongosh

Una vez dentro del shell, verá un prompt test>. Cambiemos a una nueva base de datos llamada salesdb e insertemos algunos datos de productos de ejemplo. MongoDB creará la base de datos y la colección automáticamente cuando inserte datos en ellas por primera vez.

Copie y pegue los siguientes comandos en el shell mongosh:

use salesdb
db.products.insertMany([
  { category: "Electronics", brand: "Apple", price: 1200 },
  { category: "Electronics", brand: "Samsung", price: 800 },
  { category: "Electronics", brand: "Sony", price: 950 },
  { category: "Apparel", brand: "Nike", price: 150 },
  { category: "Apparel", brand: "Adidas", price: 120 },
  { category: "Books", brand: "Penguin", price: 25 },
  { category: "Books", brand: "Penguin", price: 35 }
]);

Ahora que tiene datos, puede realizar una agregación. El siguiente comando agrupa los documentos por el campo category y calcula el precio total para cada categoría utilizando el acumulador $sum.

db.products.aggregate([
  {
    $group: {
      _id: "$category",
      totalPrice: { $sum: "$price" }
    }
  }
]);

Salida de ejemplo:

[
  { "_id": "Books", "totalPrice": 60 },
  { "_id": "Apparel", "totalPrice": 270 },
  { "_id": "Electronics", "totalPrice": 2950 }
]

Analicemos la etapa de agregación:

  • db.products.aggregate([...]): Este es el método utilizado para realizar la agregación. Toma una matriz de etapas, formando un pipeline.
  • $group: Este es el operador de etapa que agrupa los documentos de entrada.
  • _id: "$category": Esta expresión especifica la clave por la que agrupar. Aquí, agrupamos por el valor del campo category. El prefijo $ indica una ruta de campo.
  • totalPrice: { $sum: "$price" }: Este es un acumulador. Define un nuevo campo en el documento de salida llamado totalPrice. El operador $sum calcula la suma del campo price para todos los documentos del grupo.

Usar Múltiples Acumuladores

La etapa $group puede calcular múltiples agregaciones simultáneamente. Puede calcular promedios, encontrar valores mínimos o máximos, y contar elementos dentro de cada grupo. Este paso demuestra cómo usar varios acumuladores en una única etapa $group.

Debería seguir estando en el shell mongosh, utilizando la base de datos salesdb.

Escribamos una agregación más compleja que calcule el precio total, el precio promedio y la cantidad de productos para cada categoría.

db.products.aggregate([
  {
    $group: {
      _id: "$category",
      totalPrice: { $sum: "$price" },
      averagePrice: { $avg: "$price" },
      productCount: { $sum: 1 }
    }
  }
]);

Salida de ejemplo:

[
  {
    "_id": "Books",
    "totalPrice": 60,
    "averagePrice": 30,
    "productCount": 2
  },
  {
    "_id": "Apparel",
    "totalPrice": 270,
    "averagePrice": 135,
    "productCount": 2
  },
  {
    "_id": "Electronics",
    "totalPrice": 2950,
    "averagePrice": 983.3333333333334,
    "productCount": 3
  }
]

Aquí están los nuevos acumuladores que utilizamos:

  • averagePrice: { $avg: "$price" }: El operador $avg calcula el promedio del campo price para todos los documentos del grupo.
  • productCount: { $sum: 1 }: Esta es una forma común de contar documentos en un grupo. Por cada documento, suma 1 al total, contando efectivamente los documentos.

Filtrar Datos Agrupados

Después de agrupar datos, a menudo necesita filtrar los grupos basándose en los valores calculados. Por ejemplo, podría querer ver solo las categorías donde las ventas totales superan una cierta cantidad. La etapa $match se utiliza para este propósito. Puede colocarse después de una etapa $group para filtrar los documentos agrupados.

Busquemos las categorías donde el precio total de los productos es mayor que 500.

db.products.aggregate([
  {
    $group: {
      _id: "$category",
      totalPrice: { $sum: "$price" }
    }
  },
  {
    $match: {
      totalPrice: { $gt: 500 }
    }
  }
]);

Salida de ejemplo:

[{ "_id": "Electronics", "totalPrice": 2950 }]

En este pipeline:

  1. La etapa $group primero calcula el totalPrice para cada categoría.
  2. Los documentos de salida de la etapa $group se pasan luego a la etapa $match.
  3. La etapa $match filtra estos documentos, conservando solo aquellos donde el campo totalPrice es mayor que ($gt) 500.

Esto demuestra el poder del pipeline de agregación, donde la salida de una etapa se convierte en la entrada para la siguiente.

Ordenar Datos Agrupados

Una vez que tenga sus datos agrupados y filtrados, el paso final suele ser ordenarlos. La etapa $sort le permite ordenar los documentos basándose en uno o más campos, ya sea en orden ascendente o descendente.

Agrupemos los productos por categoría, calculemos el precio total y luego ordenemos los resultados por totalPrice en orden descendente (de mayor a menor).

db.products.aggregate([
  {
    $group: {
      _id: "$category",
      totalPrice: { $sum: "$price" }
    }
  },
  {
    $sort: {
      totalPrice: -1
    }
  }
]);

Salida de ejemplo:

[
  { "_id": "Electronics", "totalPrice": 2950 },
  { "_id": "Apparel", "totalPrice": 270 },
  { "_id": "Books", "totalPrice": 60 }
]

La etapa $sort toma un documento que especifica los campos por los que ordenar y el orden de clasificación:

  • totalPrice: -1: Esto ordena los documentos por el campo totalPrice. El valor -1 especifica un orden descendente. Para ordenar en orden ascendente, usaría 1.

También puede ordenar por varios campos. Por ejemplo, $sort: { category: 1, totalPrice: -1 } ordenaría primero por el nombre de la categoría alfabéticamente, y luego por el precio total descendente para las categorías con el mismo nombre.

Remodelar la Salida con $project

A veces, el formato de salida de la etapa $group no es exactamente lo que necesita. Por ejemplo, la clave de grupo se llama _id por defecto. La etapa $project le permite remodelar los documentos de salida añadiendo, eliminando o renombrando campos.

Construyamos un pipeline que agrupe por categoría, ordene por precio total y luego remodele la salida para tener un nombre de campo más descriptivo para la categoría.

db.products.aggregate([
  {
    $group: {
      _id: "$category",
      totalPrice: { $sum: "$price" }
    }
  },
  {
    $sort: {
      totalPrice: -1
    }
  },
  {
    $project: {
      _id: 0,
      category: "$_id",
      total: "$totalPrice"
    }
  }
]);

Salida de ejemplo:

[
  { "category": "Electronics", "total": 2950 },
  { "category": "Apparel", "total": 270 },
  { "category": "Books", "total": 60 }
]

La etapa $project funciona de la siguiente manera:

  • _id: 0: Esto excluye el campo _id de la salida. Por defecto, _id siempre se incluye a menos que se excluya explícitamente.
  • category: "$_id": Esto crea un nuevo campo llamado category y le asigna el valor del campo _id existente.
  • total: "$totalPrice": Esto crea un nuevo campo llamado total y le asigna el valor del campo totalPrice.

Usar $project es una forma potente de formatear la salida final de su pipeline de agregación para aplicaciones o informes.

Resumen

En este laboratorio, ha aprendido a utilizar el pipeline de agregación de MongoDB para agrupar y analizar datos. Comenzó agrupando documentos con el operador $group y calculando sumas. Luego amplió esto utilizando múltiples acumuladores como $avg y $sum: 1 para realizar cálculos más complejos. También aprendió a encadenar etapas de agregación, utilizando $match para filtrar sus resultados agrupados, $sort para ordenarlos y $project para remodelar la salida final en un formato limpio y legible. Estas son habilidades fundamentales para cualquier desarrollador o analista de datos que trabaje con MongoDB.