$push y $addToSet: creación de arrays en grupos
Recopilará valores de documentos agrupados en arrays y eliminará duplicados con $addToSet.
$push y $addToSet: creación de arrays en grupos es una lección gratuita de MongoDB Academy en CoddyKit. Esta es la lección 2 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de MongoDB Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de MongoDB Academy incluye 4 lecciones en total.
Recopilar valores en matrices
Al agrupar documentos, a veces querrá recopilar valores individuales de campos en una matriz en lugar de calcular un agregado numérico. MongoDB proporciona dos acumuladores para ello: $push y $addToSet. Ambos crean una matriz a partir de los documentos agrupados, pero se diferencian en cómo gestionan los valores duplicados. Estos acumuladores son esenciales para generar resultados desnormalizados o agrupados.
$push: recopilar todos los valores
$push añade el valor de la expresión especificada a una matriz por cada documento del grupo. Conserva los duplicados: si varios documentos comparten el mismo valor, este aparecerá varias veces en la matriz resultante. El orden de los elementos de la matriz corresponde al orden en que se procesaron los documentos, que puede variar a menos que ordene los documentos antes de agruparlos.
db.orders.aggregate([
{
$group: {
_id: '$customerId',
// Collect all product IDs ordered by this customer
orderedProducts: { $push: '$productId' },
orderDates: { $push: '$createdAt' }
}
}
])$addToSet: recopilar valores únicos
$addToSet funciona como $push, salvo que elimina los duplicados: cada valor único se añade a la matriz una sola vez. La matriz resultante no contiene elementos repetidos, de forma similar a un conjunto matemático. El orden de los elementos de salida no está garantizado al usar $addToSet, por lo que no debe depender del orden de los elementos. Úselo cuando necesite una lista distinta de valores por grupo.
db.logs.aggregate([
{
$group: {
_id: {
year: { $year: '$timestamp' },
month: { $month: '$timestamp' }
},
// Unique users who logged in this month
uniqueUsers: { $addToSet: '$userId' },
// Every event type including duplicates
allEvents: { $push: '$eventType' }
}
}
])Insertar objetos incrustados
Puede usar $push con subdocumentos completos u objetos calculados, no solo con valores escalares. Al construir una expresión de objeto, puede recopilar varios campos de cada documento en un elemento de matriz estructurado. Esto resulta útil para crear registros de resumen que incorporen los detalles de cada documento contribuyente.
db.orders.aggregate([
{
$group: {
_id: '$customerId',
orderHistory: {
$push: {
orderId: '$_id',
amount: '$amount',
status: '$status',
date: '$createdAt'
}
}
}
}
])Combinar $push con $sort
Dado que el orden de los elementos de una matriz creada con $push depende del orden de procesamiento de los documentos, debe añadir una etapa $sort antes de $group cuando sea importante mantener el orden de la matriz recopilada. Por ejemplo, para recopilar los pedidos en orden cronológico dentro de cada grupo de clientes, ordénelos primero por fecha. Tenga en cuenta que ordenar antes de $group impide que MongoDB use muchas optimizaciones de índices, por lo que debe valorar el impacto en el rendimiento.
db.orders.aggregate([
// Sort by date first so $push produces ordered arrays
{ $sort: { createdAt: 1 } },
{
$group: {
_id: '$customerId',
ordersInChronologicalOrder: {
$push: {
orderId: '$_id',
date: '$createdAt',
amount: '$amount'
}
}
}
}
])Límites de tamaño de los documentos y crecimiento de las matrices
Los documentos de MongoDB tienen un límite de tamaño de 16 MB. Al usar $push en una etapa $group, el documento resultante podría superar este límite si un grupo contiene muchos documentos o si cada valor añadido es grande. Esto genera un error en tiempo de ejecución, no un error de esquema. Para evitarlo, filtre los datos antes de agrupar, proyecte únicamente los campos necesarios en $push o use $limit combinado con $sort para añadir solo los elementos con mejor posición.
// Safe pattern: project only needed fields before pushing
db.events.aggregate([
{ $match: { year: 2024 } },
{
$project: {
userId: 1,
eventType: 1 // exclude large 'payload' field
}
},
{
$group: {
_id: '$userId',
events: { $push: '$eventType' }
}
}
])Usar $addToSet para recopilar etiquetas únicas
Un caso de uso clásico de $addToSet es agregar etiquetas o categorías únicas de los documentos de un grupo. Por ejemplo, encontrar todas las etiquetas de habilidades únicas de las ofertas de empleo de cada empresa, o todas las categorías de productos únicas que haya comprado cada cliente. La eliminación de duplicados se realiza completamente en el servidor, sin necesidad de filtrar a nivel de la aplicación.
db.jobPostings.aggregate([
{
$group: {
_id: '$companyId',
uniqueSkills: { $addToSet: '$requiredSkills' },
totalPostings: { $sum: 1 }
}
},
{ $sort: { totalPostings: -1 } }
])Comprobar el tamaño de una matriz con $size en $project
Después de recopilar valores con $push o $addToSet, a menudo querrá saber cuántos elementos contiene la matriz. Use $size en una etapa posterior de $project o $addFields para calcular la longitud de la matriz. También puede filtrar grupos por el tamaño de la matriz usando $match con $expr y $size.
db.orders.aggregate([
{
$group: {
_id: '$customerId',
products: { $addToSet: '$productId' }
}
},
{
$addFields: {
uniqueProductCount: { $size: '$products' }
}
},
// Only customers who bought 3 or more unique products
{ $match: { uniqueProductCount: { $gte: 3 } } }
])Deshacer la agrupación después de agrupar
A veces necesita invertir un $push: tomar la matriz agrupada y volver a expandirla en documentos individuales para seguir procesándolos. La etapa $unwind hace exactamente eso. Un patrón habitual es: $group con $push para consolidar → $project para transformar → $unwind para expandir → otro $group o $match para refinar los resultados.
db.orders.aggregate([
{ $group: { _id: '$customerId', products: { $push: '$productId' } } },
// Expand back into per-product documents
{ $unwind: '$products' },
// Now further filter or group by product
{
$group: {
_id: '$products',
customerCount: { $sum: 1 }
}
},
{ $sort: { customerCount: -1 } }
])Patrón del mundo real: resumen de actividad del usuario
Un patrón habitual en producción consiste en crear un documento de resumen de actividad del usuario agrupando eventos de registro. Al usar $push y $addToSet conjuntamente, puede generar un documento que contenga todas las marcas de tiempo de los eventos (una matriz ordenada mediante $push), todas las páginas visitadas únicas (sin duplicados mediante $addToSet) y el recuento total de eventos, todo en una sola pasada de agregación.
db.pageViews.aggregate([
{ $sort: { timestamp: 1 } },
{
$group: {
_id: '$userId',
visitTimestamps: { $push: '$timestamp' },
uniquePages: { $addToSet: '$page' },
totalVisits: { $sum: 1 }
}
},
{
$addFields: {
uniquePageCount: { $size: '$uniquePages' }
}
}
])Comparación entre $push y $addToSet
Para elegir entre $push y $addToSet, pregúntese: ¿importan los duplicados? Use $push cuando necesite todos los valores, incluidos los repetidos (por ejemplo, un registro de eventos o el historial de compras). Use $addToSet cuando solo necesite valores distintos (por ejemplo, etiquetas únicas o páginas visitadas sin duplicados). Recuerde que $addToSet no garantiza ningún orden concreto de los elementos en el arreglo resultante, mientras que $push conserva el orden de inserción relativo a la entrada del pipeline.
// $push — all values, order preserved
{ $push: '$tag' } // ['mongodb', 'nosql', 'mongodb', 'database']
// $addToSet — unique values only, order not guaranteed
{ $addToSet: '$tag' } // ['mongodb', 'database', 'nosql']Comprobación rápida
Compruebe su comprensión de los conceptos de MongoDB y las bases de datos NoSQL de esta lección.
Resumen de la lección
En esta lección aprendió que: $push recopila todos los valores, incluidos los duplicados, en un arreglo, $addToSet recopila solo valores únicos sin garantizar el orden y ambos pueden insertar subdocumentos complejos y deben respetar el límite de tamaño de documento de 16 MB. A continuación, exploraremos los acumuladores $first, $last y $top/$bottom para seleccionar documentos individuales por grupo.
Aprende JavaScript con un tutor de IA — gratis
Escribe y ejecuta código real en tu navegador, obtén ayuda instantánea de un tutor de IA disponible 24/7 y continúa donde lo dejaste en la web o en la aplicación.
- Cursos
- 30
- Lecciones
- 120
Preguntas frecuentes
¿La lección «$push y $addToSet: creación de arrays en grupos» es gratis?
Sí — el texto completo de «$push y $addToSet: creación de arrays en grupos» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de MongoDB Academy, actualiza a CoddyKit PRO. El curso de MongoDB Academy incluye 4 lecciones en total.
¿Qué aprenderé en «$push y $addToSet: creación de arrays en grupos»?
Recopilará valores de documentos agrupados en arrays y eliminará duplicados con $addToSet. Practicas MongoDB Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar MongoDB Academy?
No se requiere experiencia previa. MongoDB Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 2 de 4.
¿Cuánto tiempo toma la lección «$push y $addToSet: creación de arrays en grupos»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de MongoDB Academy?
Sí. Cada lección de MongoDB Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- $sum, $avg, $min y $max: agregación numérica
- $push y $addToSet: creación de arrays en grupos
- Acumuladores $first, $last y $top/$bottom
- Funciones de ventana con $setWindowFields