Portal Community

When to Use

Configuration

SettingRequiredDescription
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

OperationExpression VariablesReturnsDescription
filteritem — current elementArray (subset)Evaluates the expression for each element. Keeps only elements where the expression is truthy. item.status === "active" keeps only active items.
mapitem — current elementArray (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.
reduceacc — accumulator, item — current elementScalar or objectFolds the collection to a single value. acc + item.total with InitialValue: 0 produces a sum. acc + item.name + ", " concatenates names.
sortn/a — uses Field and DirectionArray (sorted)Sorts by the specified field in ascending or descending order. Uses natural comparison for strings and numeric comparison for numbers.
distinctn/a — uses FieldArray (deduplicated)Returns unique elements. For object arrays, specify Field to deduplicate by field value. For primitive arrays, omit Field.
countitem — optional filter expressionIntegerReturns the total number of elements. When Expression is provided, counts only elements where the expression is truthy.
firstitem — optional filter expressionObject or nullReturns the first element. When Expression is provided, returns the first element matching the expression.
lastitem — optional filter expressionObject or nullReturns the last element. When Expression is provided, returns the last element matching the expression.
reversen/aArray (reversed)Returns the array in reverse order. Does not sort — simply reverses the existing element order.

Output Ports

PortWhen It Fires
successThe operation completed without error. The result is available in the result output field.
errorThe 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

FieldTypeDescription
resultanyThe result of the operation. An array for filter/map/sort/distinct/reverse; a scalar or object for reduce/count/first/last.
operationstringThe operation name that was executed (e.g., "filter"). Useful for logging in generic processing pipelines.
countintegerFor 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

ExpressionValue
{{ $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

PolicyRationale
Check count before iterating the resultA 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 expressionsEvery 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 InitialValueWithout 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 FunctionCollectionOperation 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)