When to Use
- Filter orders by status: An API returns all orders for a customer. Use
filter with item.status === "active" to keep only the orders that need processing — no CodeExecute required.
- Map documents to extract just IDs: A database query returns full order objects. Use
map with expression item.orderId to produce a clean array of order IDs for a bulk-cancel API call.
- Count total active items: Before routing to an approval workflow, use
count with item.isActive === true to determine how many items require attention. Branch on the count with a downstream IfCondition node.
- Sort employees by timestamp descending: A queue of pending approvals needs to be processed oldest-first. Use
sort with Field: "createdAt" and Direction: "asc" to order the array correctly.
- Get distinct values of a field: An event log contains multiple entries per region. Use
distinct with Field: "region" to get a unique list of affected regions for targeted notifications.
Configuration
| Setting | Required | Description |
Operation |
Required |
The operation to perform on the collection. One of: filter, map, reduce, sort, distinct, count, first, last, reverse. |
Collection |
Optional |
An inline JSON array literal. Use for static data or testing. If omitted, the node uses SourceOutput to locate the collection from a previous node's output. |
SourceOutput |
Optional |
The node key of an upstream node whose output array should be used as the collection. The node expects the output to be (or contain) an array. |
Expression |
Optional |
A JavaScript-compatible expression evaluated per item (for filter, map) or per accumulator step (for reduce). Access the current element as item. For reduce, use acc and item. Required for filter, map, and reduce. |
Field |
Optional |
Field name used by sort (the field to sort by) and distinct (the field to deduplicate on). For primitive arrays, omit this field. |
Direction |
Optional |
Sort direction for the sort operation. "asc" (default) or "desc". |
InitialValue |
Optional |
The starting accumulator value for the reduce operation. Common values: 0 (sum), "" (string concatenation), [] (array building). Defaults to null if omitted. |
Operations Reference
| Operation | Expression Variables | Returns | Description |
filter | item — current element | Array (subset) | Evaluates the expression for each element. Keeps only elements where the expression is truthy. item.status === "active" keeps only active items. |
map | item — current element | Array (transformed) | Transforms each element by evaluating the expression. item.id returns an array of ID strings. { id: item.id, label: item.name } returns reshaped objects. |
reduce | acc — accumulator, item — current element | Scalar or object | Folds the collection to a single value. acc + item.total with InitialValue: 0 produces a sum. acc + item.name + ", " concatenates names. |
sort | n/a — uses Field and Direction | Array (sorted) | Sorts by the specified field in ascending or descending order. Uses natural comparison for strings and numeric comparison for numbers. |
distinct | n/a — uses Field | Array (deduplicated) | Returns unique elements. For object arrays, specify Field to deduplicate by field value. For primitive arrays, omit Field. |
count | item — optional filter expression | Integer | Returns the total number of elements. When Expression is provided, counts only elements where the expression is truthy. |
first | item — optional filter expression | Object or null | Returns the first element. When Expression is provided, returns the first element matching the expression. |
last | item — optional filter expression | Object or null | Returns the last element. When Expression is provided, returns the last element matching the expression. |
reverse | n/a | Array (reversed) | Returns the array in reverse order. Does not sort — simply reverses the existing element order. |
Output Ports
| Port | When It Fires |
success | The operation completed without error. The result is available in the result output field. |
error | The collection could not be resolved, the expression contains a syntax error, or a runtime evaluation error occurs during filter/map/reduce. Error details include the expression that failed and the element at which the error occurred. |
Output Fields
| Field | Type | Description |
result | any | The result of the operation. An array for filter/map/sort/distinct/reverse; a scalar or object for reduce/count/first/last. |
operation | string | The operation name that was executed (e.g., "filter"). Useful for logging in generic processing pipelines. |
count | integer | For array-returning operations, the number of elements in the result array. For the count operation, the count value itself. |
Sample Configurations
Filter — only active orders
{
"nodeType": "collection-operation",
"settings": {
"Operation": "filter",
"SourceOutput": "getOrdersNode",
"Expression": "item.status === \"active\""
}
}
Map — extract order IDs only
{
"nodeType": "collection-operation",
"settings": {
"Operation": "map",
"SourceOutput": "getOrdersNode",
"Expression": "item.orderId"
}
}
Reduce — sum all line item amounts
{
"nodeType": "collection-operation",
"settings": {
"Operation": "reduce",
"SourceOutput": "getLineItemsNode",
"Expression": "acc + item.amount",
"InitialValue": 0
}
}
Sort — newest records first
{
"nodeType": "collection-operation",
"settings": {
"Operation": "sort",
"SourceOutput": "getRecordsNode",
"Field": "createdAt",
"Direction": "desc"
}
}
Sample Output
Success Port
{
"results": [
{ "id": "item_001", "name": "Widget A", "processedAt": "2025-03-15T10:00:00Z", "status": "processed" },
{ "id": "item_002", "name": "Widget B", "processedAt": "2025-03-15T10:00:01Z", "status": "processed" },
{ "id": "item_003", "name": "Widget C", "processedAt": "2025-03-15T10:00:02Z", "status": "skipped", "skipReason": "already_exists" }
],
"summary": {
"totalItems": 3,
"processedCount": 2,
"skippedCount": 1,
"errorCount": 0,
"durationMs": 847
}
}
Expression Reference
| Expression | Value |
{{ $output.collectionOp.result }} | The full result (array or scalar) of the operation. |
{{ $output.collectionOp.count }} | The count of result items — useful for downstream IfCondition branching on empty results. |
{{ $output.collectionOp.operation }} | The operation name string for logging. |
Node Policies & GuardRails
| Policy | Rationale |
Check count before iterating the result | A filter or first operation may return an empty array or null. Always add a downstream IfCondition checking {{ $output.collectionOp.count }} > 0 before a Loop node to prevent empty-iteration errors. |
Use item variable — not the source field name — in expressions | Every element in the collection is exposed as item regardless of the field names in the source object. Write item.status, not order.status or $.status. |
Use reduce with explicit InitialValue | Without an initial value, reduce uses the first element as the starting accumulator, which can produce unexpected results when the first element is an object. Always provide a typed initial value matching your expected accumulation type. |
| For complex multi-step transformations, use CodeExecute or Function | CollectionOperation is designed for single-operation array manipulation. When you need to chain multiple operations (filter then map then sort), either use multiple CollectionOperation nodes in sequence or a single CodeExecute/Function node. |
Pattern Examples
Pattern 1 — Filter Active Subscriptions, Then Extract IDs for Bulk Email
// Node 1: CollectionOperation — filter active only
{
"Operation": "filter",
"SourceOutput": "getAllSubscriptionsNode",
"Expression": "item.status === \"active\" && item.tier === \"premium\""
}
// result: array of premium active subscription objects
// Node 2: CollectionOperation — extract customer email addresses
{
"Operation": "map",
"SourceOutput": "filterActiveNode",
"Expression": "item.customerEmail"
}
// result: array of email strings ready for bulk email send
Pattern 2 — Count Pending Approvals and Branch on Threshold
// CollectionOperation — count pending items
{
"Operation": "count",
"SourceOutput": "getPendingApprovalsNode",
"Expression": "item.status === \"pending\""
}
// Downstream VariableAssignment — store the count
{
"VariableName": "pendingCount",
"ValueExpression": "{{ $output.countNode.count }}"
}
// Downstream IfCondition — route differently if count exceeds threshold
// Condition: {{ $var.pendingCount }} > 50
Pattern 3 — Sum Invoice Totals and Get Distinct Regions
// Node 1: Sum all invoice amounts
{
"Operation": "reduce",
"SourceOutput": "getInvoicesNode",
"Expression": "acc + item.totalAmount",
"InitialValue": 0
}
// Node 2: Get distinct billing regions from the same invoices
{
"Operation": "distinct",
"SourceOutput": "getInvoicesNode",
"Field": "billingRegion"
}
// result: ["EMEA", "APAC", "AMER"] (unique regions only)