Make.com collections are arrays of data that flow between modules in your scenarios. Understanding how to work with collections effectively is crucial for processing multiple items, iterating through datasets, and building scalable automation workflows.
Collections in Make.com are arrays of bundles (data objects) that can be processed individually or as a group. When a module outputs multiple items, Make.com treats this as a collection.
// Example collection structure
const collection = [
{ id: 1, name: "Item 1", price: 29.99 },
{ id: 2, name: "Item 2", price: 39.99 },
{ id: 3, name: "Item 3", price: 19.99 }
];
When your JavaScript module receives a collection, Make.com typically processes each item individually:
// Input will be a single item from the collection
const item = input; // { id: 1, name: "Item 1", price: 29.99 }
// Process the individual item
const processedItem = {
id: item.id,
name: item.name.toUpperCase(),
price: item.price,
discountedPrice: item.price * 0.9,
category: item.price > 30 ? 'premium' : 'standard',
processedAt: new Date().toISOString()
};
return processedItem;
To process the entire collection at once, use an aggregator module before your JavaScript module:
// After using an aggregator, input contains the full array
const items = input.array || [];
// Process the entire collection
const summary = {
totalItems: items.length,
totalValue: items.reduce((sum, item) => sum + (item.price || 0), 0),
averagePrice: 0,
categories: {},
priceRanges: {
budget: items.filter(item => item.price < 25).length,
standard: items.filter(item => item.price >= 25 && item.price < 50).length,
premium: items.filter(item => item.price >= 50).length
}
};
// Calculate average price
summary.averagePrice = summary.totalItems > 0 ?
summary.totalValue / summary.totalItems : 0;
// Group by categories
items.forEach(item => {
const category = item.category || 'uncategorized';
summary.categories[category] = (summary.categories[category] || 0) + 1;
});
return summary;
// Process input and return an array to create a collection
const baseData = input.data || {};
const variations = input.variations || ['small', 'medium', 'large'];
// Create multiple items from single input
const collectionItems = variations.map(variation => ({
id: `${baseData.id}-${variation}`,
name: `${baseData.name} (${variation})`,
size: variation,
price: calculatePrice(baseData.basePrice, variation),
sku: generateSKU(baseData.id, variation),
createdAt: new Date().toISOString()
}));
function calculatePrice(basePrice, size) {
const multipliers = { small: 0.8, medium: 1.0, large: 1.2 };
return basePrice * (multipliers[size] || 1.0);
}
function generateSKU(baseId, size) {
return `${baseId}-${size.toUpperCase()}-${Date.now()}`;
}
// Return array to create collection
return collectionItems;
// Create collections based on conditions
const orders = input.orders || [];
const processedOrders = [];
orders.forEach(order => {
// Process each order
const processedOrder = {
orderId: order.id,
customerName: order.customer.name,
orderDate: order.date,
status: order.status
};
// Add to collection if meets criteria
if (order.status === 'pending' && order.total > 100) {
processedOrders.push({
...processedOrder,
priority: 'high',
requiresApproval: true
});
} else if (order.status === 'pending') {
processedOrders.push({
...processedOrder,
priority: 'normal',
requiresApproval: false
});
}
// Skip cancelled or completed orders
});
return processedOrders;
// Filter collection based on criteria
const allItems = input.items || [];
const filteredItems = allItems.filter(item => {
// Multiple filter conditions
const isActive = item.status === 'active';
const hasStock = item.inventory > 0;
const isInPriceRange = item.price >= 10 && item.price <= 1000;
const hasValidCategory = item.category && item.category.trim().length > 0;
return isActive && hasStock && isInPriceRange && hasValidCategory;
});
// Add filter metadata
const filterResults = filteredItems.map(item => ({
...item,
filtered: true,
filterAppliedAt: new Date().toISOString(),
originalIndex: allItems.indexOf(item)
}));
return {
filteredItems: filterResults,
originalCount: allItems.length,
filteredCount: filterResults.length,
filterEfficiency: (filterResults.length / allItems.length * 100).toFixed(2) + '%'
};
// Sort collection by multiple criteria
const items = input.items || [];
// Sort by priority, then by date, then by name
const sortedItems = items.sort((a, b) => {
// Primary sort: priority (high > medium > low)
const priorityOrder = { high: 3, medium: 2, low: 1 };
const priorityDiff = (priorityOrder[b.priority] || 0) - (priorityOrder[a.priority] || 0);
if (priorityDiff !== 0) return priorityDiff;
// Secondary sort: date (newest first)
const dateA = new Date(a.createdAt || 0);
const dateB = new Date(b.createdAt || 0);
const dateDiff = dateB - dateA;
if (dateDiff !== 0) return dateDiff;
// Tertiary sort: name (alphabetical)
return (a.name || '').localeCompare(b.name || '');
});
// Add sort metadata
const sortedWithMetadata = sortedItems.map((item, index) => ({
...item,
sortOrder: index + 1,
sortedAt: new Date().toISOString()
}));
return sortedWithMetadata;
// Group collection items by category
const items = input.items || [];
const groupedItems = items.reduce((groups, item) => {
const category = item.category || 'uncategorized';
if (!groups[category]) {
groups[category] = {
categoryName: category,
items: [],
count: 0,
totalValue: 0,
averagePrice: 0
};
}
groups[category].items.push(item);
groups[category].count++;
groups[category].totalValue += item.price || 0;
groups[category].averagePrice = groups[category].totalValue / groups[category].count;
return groups;
}, {});
// Convert to array format for Make.com collection
const groupedArray = Object.values(groupedItems).map(group => ({
...group,
groupId: group.categoryName.toLowerCase().replace(/\s+/g, '-'),
createdAt: new Date().toISOString()
}));
return groupedArray;
// Process large collections in batches
const allItems = input.items || [];
const batchSize = 50;
function processBatch(items, batchIndex) {
return items.map((item, itemIndex) => ({
...item,
batchId: batchIndex,
itemIndex: itemIndex,
globalIndex: (batchIndex * batchSize) + itemIndex,
processedAt: new Date().toISOString(),
batchProcessed: true
}));
}
// Create batches
const batches = [];
for (let i = 0; i < allItems.length; i += batchSize) {
const batch = allItems.slice(i, i + batchSize);
const processedBatch = processBatch(batch, Math.floor(i / batchSize));
batches.push({
batchIndex: Math.floor(i / batchSize),
itemCount: batch.length,
items: processedBatch,
batchCreatedAt: new Date().toISOString()
});
}
return {
batches: batches,
totalBatches: batches.length,
totalItems: allItems.length,
batchSize: batchSize
};
// Merge multiple collections
const collection1 = input.collection1 || [];
const collection2 = input.collection2 || [];
const collection3 = input.collection3 || [];
// Merge with source tracking
const mergedCollection = [
...collection1.map(item => ({ ...item, source: 'collection1' })),
...collection2.map(item => ({ ...item, source: 'collection2' })),
...collection3.map(item => ({ ...item, source: 'collection3' }))
];
// Remove duplicates based on ID
const uniqueItems = mergedCollection.reduce((unique, item) => {
const existingItem = unique.find(u => u.id === item.id);
if (!existingItem) {
unique.push({
...item,
mergedAt: new Date().toISOString(),
isDuplicate: false
});
} else {
// Handle duplicate - keep the one from the preferred source
const sourcePreference = ['collection1', 'collection2', 'collection3'];
const currentPreference = sourcePreference.indexOf(existingItem.source);
const newPreference = sourcePreference.indexOf(item.source);
if (newPreference < currentPreference) {
// Replace with higher priority source
const index = unique.indexOf(existingItem);
unique[index] = {
...item,
mergedAt: new Date().toISOString(),
isDuplicate: true,
replacedSource: existingItem.source
};
}
}
return unique;
}, []);
return {
mergedItems: uniqueItems,
originalCounts: {
collection1: collection1.length,
collection2: collection2.length,
collection3: collection3.length
},
finalCount: uniqueItems.length,
duplicatesRemoved: mergedCollection.length - uniqueItems.length
};
// Optimize for large collections
const items = input.items || [];
// Use Map for O(1) lookups instead of array.find()
const categoryMap = new Map();
const processedItems = [];
// Single pass processing
for (const item of items) {
// Process item
const processedItem = {
id: item.id,
name: item.name,
processedAt: new Date().toISOString()
};
// Update category statistics efficiently
const category = item.category || 'uncategorized';
if (!categoryMap.has(category)) {
categoryMap.set(category, { count: 0, totalValue: 0 });
}
const categoryStats = categoryMap.get(category);
categoryStats.count++;
categoryStats.totalValue += item.price || 0;
processedItems.push(processedItem);
}
// Convert Map to object for output
const categoryStats = Object.fromEntries(
Array.from(categoryMap.entries()).map(([category, stats]) => [
category,
{
...stats,
averagePrice: stats.totalValue / stats.count
}
])
);
return {
processedItems,
categoryStats,
totalProcessed: processedItems.length
};
// Process large collections without storing everything in memory
const items = input.items || [];
let processedCount = 0;
const summary = {
totalValue: 0,
maxPrice: 0,
minPrice: Infinity,
categories: new Set()
};
// Process items one by one without storing results
for (const item of items) {
if (item.price && typeof item.price === 'number') {
summary.totalValue += item.price;
summary.maxPrice = Math.max(summary.maxPrice, item.price);
summary.minPrice = Math.min(summary.minPrice, item.price);
}
if (item.category) {
summary.categories.add(item.category);
}
processedCount++;
}
// Return summary instead of full processed collection
return {
summary: {
totalItems: processedCount,
totalValue: summary.totalValue,
averagePrice: processedCount > 0 ? summary.totalValue / processedCount : 0,
maxPrice: summary.maxPrice === 0 ? 0 : summary.maxPrice,
minPrice: summary.minPrice === Infinity ? 0 : summary.minPrice,
uniqueCategories: Array.from(summary.categories),
categoryCount: summary.categories.size
},
processedAt: new Date().toISOString()
};
Working effectively with Make.com collections enables you to build powerful automation workflows that can handle complex data processing scenarios at scale.