Módulo 3: Loops e Iteraciones
Aggregate: Juntar Resultados
Descripción de la cápsula
Iteración (implícita o explícita) procesa N items independientemente — cada uno con su propia ejecución. Pero a veces necesitas el resultado combinado al final: un mensaje resumen con todos los items, un reporte con todas las filas procesadas, un único request a una API que acepta batch. Aggregate es el nodo que colapsa N items en 1 con los datos juntados.
En esta cápsula vas a aprender los modos de Aggregate, los casos típicos de uso (resumen, batch request, transformación a array), las decisiones de diseño (cuándo aggregate vs procesamiento individual), y las trampas al combinar Aggregate con SplitInBatches.
Lo que vas a aprender
Al terminar esta cápsula serás capaz de:
- ✅ Entender qué hace Aggregate y cuándo aplicarlo
- ✅ Configurar los modos principales
- ✅ Aplicar a 4 casos típicos comunes
- ✅ Combinar con SplitInBatches correctamente
- ✅ Decidir cuándo aggregate vs no según necesidad
El modelo: de N items a 1
Aggregate convierte N items en 1 item con un campo que es un array con los N items originales.
Antes:
[ { name: "Mike", amount: 100 }, { name: "Ana", amount: 200 }, { name: "Luis", amount: 150 } ]Después de Aggregate:
[ { all_items: [ { name: "Mike", amount: 100 }, { name: "Ana", amount: 200 }, { name: "Luis", amount: 150 } ] } ]
Un solo item, con un array all_items adentro que contiene los N originales.
Configuración del Aggregate node
Modo principal: Aggregate All Item Data
- Aggregate:
All Item Data (Into a Single List) - Put Output in Field: nombre del campo donde se guarda el array (default
dataoaggregated)
Modo: Individual Fields
Para aggregar campos específicos:
- Aggregate:
Individual Fields - Field to Aggregate: ej.
email - Output:
{ "email": ["a@x.com", "b@y.com", "c@z.com"] }— array solo de emails
Modo: All Item Data with Field
Combinación: keep all data + algunos campos extraídos como arrays.
Caso 1: Resumen / reporte agregado
Caso: procesar 50 leads, mandar 1 mensaje a Slack con la lista completa, no 50 mensajes.
[Sheet: 50 leads]
│
[Set: agregar processed_at]
│
[Aggregate: all data into 'leads_list']
│
[Slack: send 1 message]
Mensaje:
📊 *Reporte de leads del día*
Total: {{ $json.leads_list.length }}
{{ $json.leads_list.map(l => '• ' + l.name + ' (' + l.email + ')').join('\n') }}
Resultado: 1 mensaje en Slack con la lista de los 50 leads.
Caso 2: Batch API request
Caso: una API acepta batch creation (recibir array, crear N registros en 1 request).
[N leads]
│
[Aggregate: emails into 'emails_array']
│
[HTTP POST: { "emails": $json.emails_array }]
1 request en vez de N. Más eficiente y respetuoso con rate limits.
Caso 3: Transformación a CSV/JSON único
Caso: quieres exportar items a un archivo CSV o JSON.
[N items]
│
[Aggregate: all data]
│
[Code o Function: convertir array a CSV string]
│
[Write File / Send Email con attachment]
Caso 4: Calcular total / estadísticas
Caso: sumar el monto total de N pedidos.
[N pedidos]
│
[Aggregate: amounts into 'amounts']
│
[Set:]
total: {{ $json.amounts.reduce((a,b) => a+b, 0) }}
average: {{ $json.amounts.reduce((a,b) => a+b, 0) / $json.amounts.length }}
max: {{ Math.max(...$json.amounts) }}
Aggregate dentro de SplitInBatches (cuidado)
Si tienes:
[SplitInBatches batch=10]
│
[procesa cada batch]
│
[Aggregate dentro del loop?]
Cuidado: Aggregate solo "ve" los items del batch actual. Si quieres aggregate del total, debes hacerlo:
Opción A: Aggregate después del loop (Done branch)
[SplitInBatches] → [procesa] → [guarda resultado parcial en Sheet]
│
└─→ loop
│
↓
[Done]
│
[Lee Sheet con todos los resultados]
│
[Aggregate global]
│
[reporte final]
Cada batch guarda resultados parciales. Al final del loop, lees todos los parciales y haces Aggregate.
Opción B: Aggregate en cada batch + acumulador
Más complejo — mantener un estado entre batches. Generalmente no vale la pena vs opción A.
Decisión: ¿aggregate o no?
Aggregate cuando:
- Necesitas 1 resultado / mensaje / request con todos los items
- API acepta batch (1 request con array vs N requests)
- Reportes / resúmenes
- Cálculos sobre el set completo (total, promedio)
NO aggregate cuando:
- Cada item necesita procesamiento independiente (mandar email a cada uno)
- Items van a destinos distintos (Switch por categoría)
- Volumen muy alto (Aggregate carga todo en memoria — puede ser issue con miles de items)
Operaciones útiles sobre arrays agregados
Una vez que tienes el array, puedes manipularlo:
// Filtrar
$json.items.filter(i => i.active)
// Map (extraer campo)
$json.items.map(i => i.email)
// Sumar
$json.items.reduce((a, b) => a + b.amount, 0)
// Group by (manual)
{{
$json.items.reduce((acc, item) => {
if (!acc[item.category]) acc[item.category] = [];
acc[item.category].push(item);
return acc;
}, {})
}}
// Sort
$json.items.sort((a, b) => b.amount - a.amount) // descendente por monto
// Top N
$json.items.sort(...).slice(0, 10) // top 10
Trampas comunes
Trampa 1: Aggregate cuando querías iteración
Qué pasa: Aggregate antes de Slack. Esperabas 1 mensaje por item — recibes 1 con la lista. O viceversa.
Cómo evitar: Pensar antes: ¿necesitas N notificaciones (uno por item) o 1 resumen?
Trampa 2: Aggregate después de operación costosa
Qué pasa: Procesas 1000 items con API (cara). Después Aggregate. Pero solo querías estadísticas — no necesitabas procesar todos individualmente.
Cómo evitar: Aggregate temprano si vas a hacer cálculos sobre el set, no individual.
Trampa 3: Confundir cómo se ve el output
Qué pasa: Después del Aggregate, esperabas seguir usando $json.email como antes. Ahora necesitas $json.items[0].email.
Cómo evitar: Inspeccionar el output del Aggregate (vista Schema, G1-M06-03) para ver la estructura nueva.
Trampa 4: Aggregate con datos heterogéneos
Qué pasa: Tu input tiene items con structuras distintas. Aggregate junta todos pero el array resultante es difícil de procesar.
Cómo evitar: Normalizar antes de Aggregate. Set previo que da estructura uniforme a todos los items.
Trampa 5: Aggregate con miles de items y memoria limitada
Qué pasa: Aggregate de 10,000 items grandes (cada uno con binary o muchos campos). Memoria de n8n se satura.
Cómo evitar:
- Para volumen masivo, procesar en batches y guardar resultados parciales en DB/Sheet
- Aggregate solo si memoria razonable
Aggregate vs Merge
Quizás te preguntes la diferencia:
| Aggregate | Merge |
|---|---|
| Toma 1 input con N items | Toma 2+ inputs con items separados |
| Colapsa N items en 1 | Combina items de diferentes streams |
| Resultado: 1 item con array | Resultado: combinación según modo |
| Caso: resumen de items | Caso: unir Sheet con CRM API |
No son intercambiables. Cada uno para su caso.
Ejemplo completo: reporte de leads diario
[Schedule: 6am diario]
│
[Sheet: leads del día]
│
[Filter: válidos]
│
[Set: enriquecer con score]
│
[Aggregate: all data into 'leads']
│
[Set: calcular stats]
total: {{ $json.leads.length }}
total_amount: {{ $json.leads.reduce((a, b) => a + Number(b.amount), 0) }}
top_3: {{ $json.leads.sort((a, b) => b.score - a.score).slice(0, 3) }}
│
[Slack: reporte]
📊 *Reporte diario*
Total leads: {{ $json.total }}
Valor total: ${{ $json.total_amount }}
*Top 3:*
{{ $json.top_3.map((l, i) => (i+1) + '. ' + l.name + ' (score: ' + l.score + ')').join('\n') }}
Resultado: 1 mensaje diario con stats y top 3, en lugar de 50 mensajes individuales.
Ejercicio: refactorizar a Aggregate
Objetivo: practicar identificar oportunidades.
Workflow original
[Sheet: 100 pedidos del día]
│
[Slack: enviar mensaje por cada pedido]
100 mensajes saturando el canal.
Tu tarea
Refactoriza a:
- 1 mensaje resumen con stats
- Total de pedidos
- Monto total
- Top 5 por monto
Solución
[Sheet: 100 pedidos]
│
[Aggregate: all into 'orders']
│
[Set:]
- total: $json.orders.length
- total_amount: $json.orders.reduce((a,b) => a + Number(b.amount), 0)
- top_5: $json.orders.sort((a,b) => b.amount - a.amount).slice(0, 5)
│
[Slack: 1 mensaje]
100 mensajes → 1.
Resumen y siguiente paso
- Aggregate colapsa N items en 1 con array adentro
- Modos: all data, individual fields, all + field
- 4 casos típicos: resumen, batch API, transformación, estadísticas
- Aggregate + SplitInBatches: Aggregate al final del loop (Done branch), no dentro
- Aggregate vs Merge: distintas operaciones, no intercambiables
- 5 trampas: aggregate cuando querías iteración, después de procesamiento costoso, confundir estructura, datos heterogéneos, memoria con miles
Antes de avanzar deberías poder:
- Decidir cuándo Aggregate vs iteración individual
- Acceder a campos del array agregado
- Hacer cálculos sobre el array (sum, top N, etc.)
Lo que sigue (cápsula 07):
Loops complejos: paginación de APIs (real, no simplificada), retry strategies sofisticadas, loops con condiciones de salida dinámicas. Los patrones que aparecen en integraciones reales.
Recursos adicionales
- Aggregate Node Documentation - Referencia.
- Array Methods (MDN) - map, filter, reduce, etc.
Creado: Mayo 11, 2026 Versión: 1.0