Глава 4. Управление потоком данных
В реальных воркфлоу редко всё идёт по одному пути. Нужно фильтровать записи, разветвлять логику, объединять результаты из нескольких веток и итерировать по большим спискам. Для этого в n8n есть четыре ключевых ноды управления потоком.
IF — ветвление по условию
Нода IF делит поток данных на два пути: true и false. Каждый входящий айтем проверяется против заданных условий и уходит в соответствующую ветку.
Операторы сравнения
| Тип данных | Доступные операторы |
|---|---|
| String | equals, not equals, contains, not contains, starts with, ends with, matches regex, is empty, is not empty |
| Number | equals, not equals, greater than, less than, greater or equal, less or equal |
| Boolean | is true, is false |
| Array | contains, not contains, length equals, is empty |
| DateTime | before, after, between |
| Object | has key, has value |
Пример: фильтр заказов по сумме
Допустим, из HTTP Request приходят заказы. Нужно отправить в Slack только те, где total > 1000:
- Добавьте ноду IF после ноды с данными.
- В поле Value 1 введите через выражение:
{{ $json.total }} - Операция: Greater Than
- Value 2:
1000
К true-выходу подключите нотификацию в Slack, к false — завершение или другую логику.
Несколько условий
Нажмите Add condition для добавления дополнительных проверок. Переключатель AND / OR в верхней части определяет, как они комбинируются:
- AND — айтем попадёт в true только если ВСЕ условия выполнены
- OR — достаточно хотя бы одного
Условие 1: {{ $json.status }} equals "active"
AND
Условие 2: {{ $json.total }} greater than 500Совет
Используйте выражения для динамических значений в полях условия. Например, сравнивайте поле с результатом другой ноды через {{ $('НодаИмя').item.json.minValue }}.
Switch — маршрутизация по множеству путей
Когда путей больше двух, IF превращается в цепочку, которую тяжело читать. Switch позволяет задать сколько угодно правил, каждое с собственным выходом.
Режимы работы
Rules (правила) — каждое правило — это условие + имя выхода:
| Правило | Условие | Выход |
|---|---|---|
| 1 | {{ $json.country }} equals "RU" | russia |
| 2 | {{ $json.country }} equals "DE" | germany |
| 3 | — (нет условия) | fallback |
Выход без условия называется Fallback output — туда попадают айтемы, не подошедшие ни под одно правило.
Expression — весь роутинг определяется одним выражением JavaScript, результат которого — имя выхода. Подходит для динамической маршрутизации.
Несколько совпадений
По умолчанию Switch отправляет айтем в первый совпавший выход. Включите Send to all matching outputs — айтем продублируется во все подходящие ветки.
Merge — объединение веток
После разветвления часто нужно собрать данные обратно. Нода Merge соединяет потоки из двух входов (Input 1 и Input 2).
Режимы Merge
Append
Просто дописывает айтемы Input 2 после айтемов Input 1. Дубликаты не убираются.
Input 1: [{name: "Alice"}, {name: "Bob"}]
Input 2: [{name: "Carol"}]
Result: [{name: "Alice"}, {name: "Bob"}, {name: "Carol"}]Combine — By Position
Объединяет айтемы попарно по позиции (первый с первым, второй со вторым). Поля обоих айтемов сливаются в один объект.
Input 1: [{id: 1, name: "Alice"}]
Input 2: [{id: 1, score: 95}]
Result: [{id: 1, name: "Alice", score: 95}]При разном количестве айтемов лишние отбрасываются, если не включён параметр Keep unpaired items.
Combine — By Fields (Join)
SQL-подобный JOIN: айтемы объединяются по значению общего поля.
Настройки:
- Fields to match — имя поля для сопоставления (например,
id) - Output unpaired items — включить, чтобы получить поведение LEFT JOIN
Input 1: [{id: 1, name: "Alice"}, {id: 2, name: "Bob"}]
Input 2: [{id: 1, city: "Moscow"}, {id: 3, city: "Berlin"}]
By Fields on "id":
Result: [{id: 1, name: "Alice", city: "Moscow"}]Combine — Multiplex (Cartesian Product)
Каждый айтем Input 1 комбинируется с каждым айтемом Input 2. Полезно для генерации всех возможных пар.
Choose Branch
Пропускает дальше только один вход — тот, который пришёл первым, или явно выбранный (Input 1 или Input 2). Нужно для переключения между ветками без слияния данных.
Важно
Merge ждёт данные от обоих входов. Если один путь не выполнится (например, пустой IF-ветке нечего передать), Merge зависнет. Подключайте оба входа даже когда передаёте пустой массив.
Loop Over Items — итерация с паузой
n8n по умолчанию обрабатывает все айтемы сразу (bulk-режим). Loop Over Items — бывший Split in Batches — обрабатывает их порциями (батчами), возвращая управление к себе после каждого батча.
Когда нужен Loop
- Сторонний API ограничивает частоту запросов (rate limit) — нужно делать паузу
- Список слишком большой для одного запроса
- Каждый айтем требует сложной логики с несколькими нодами
Параметры
| Параметр | Описание |
|---|---|
| Batch Size | Сколько айтемов передаётся за один проход. По умолчанию 1 |
| Options → Reset | Сбросить счётчик итераций (если нода используется повторно) |
Как это работает
[10 айтемов] → Loop Over Items (batch=3)
→ [3 айтема] → HTTP Request → ... → Loop Over Items (следующий батч)
→ [3 айтема] → HTTP Request → ... → Loop Over Items
→ [3 айтема] → HTTP Request → ... → Loop Over Items
→ [1 айтем] → HTTP Request → ... → Loop Over Items
→ done output → следующая нодаВыход done срабатывает только когда все батчи обработаны. К нему подключается всё, что должно выполниться после цикла.
Пример: загрузка данных порциями
Manual Trigger
→ Code (генерируем 50 ID: [{id:1},{id:2},...])
→ Loop Over Items (batch=10)
→ HTTP Request (GET /api/items/{{ $json.id }})
→ [выход loop] → Loop Over Items
→ [done] → Aggregate → Spreadsheet File → EmailДобавление задержки
Между нодой запроса и возвратом в Loop вставьте ноду Wait (тип: After time interval, например 1 секунда) — это создаст паузу между батчами.
Практика: пайплайн с ветвлением
Рассмотрим реальный сценарий: получаем список пользователей из API, разделяем на активных и неактивных, активным отправляем email, неактивным — ставим метку в CRM.
HTTP Request (GET /users)
→ IF: {{ $json.active }} is true
true → Send Email (для каждого активного)
false → HTTP Request (PATCH /users/{{ $json.id }} - обновляем статус в CRM)
→ Merge (mode: Append)
→ Code (сводная статистика)
→ Slack (отчёт)Параллельное выполнение веток
Ветки IF/Switch выполняются последовательно, не параллельно. n8n сначала полностью отработает true-ветку, затем false-ветку.