В одном списке есть заказы и ID клиентов, в другом - названия компаний. Нужно добавить название к каждому заказу, не перепутав покупателей и не потеряв запись без совпадения. Сделаем это через Merge в n8n: соединим два потока по customer_id и проверим результат на вымышленных данных.
Результат инструкции
Соберём workflow из семи узлов. Он получит три заказа и три записи справочника, добавит к O1 компанию А, к O2 - компанию Б, а O3 сохранит без названия клиента. В результате будет поле customer_found: true для найденного непустого названия и false для отсутствующего. Все суммы заказов останутся исходными.
Результат виден в OUTPUT узла Result. Схема не меняет настоящие заказы, не записывает данные в CRM, не обращается к AI-модели и ничего не отправляет клиентам. Это проверяемое объединение двух наборов, а не поиск человека по имени или автоматическое исправление справочника.
Что понадобится
- Запущенный n8n и доступ к созданию нового workflow. Проверенная версия - 2.42.4, узел Merge 3.2.
- Пустая отдельная схема. Не используйте рабочий процесс с платежами или рассылкой.
- Готовый JSON из шага 2. Внешние аккаунты, API-ключи и платный тариф для упражнения не нужны.
Установить n8n локально через Docker
Шаг 1. Создайте новый workflow
Откройте Overview → Create workflow. Начните с пустого холста. Запуск будет ручным, через Manual Trigger и Execute workflow. Нажимать Publish не нужно: упражнение не принимает внешние события.
Шаг 2. Импортируйте готовую схему
Скачать n8n-merge-orders-demo.json
Скопируйте весь JSON файла, щёлкните свободную область пустого холста и нажмите Ctrl+V. Появится имя ezgpt-merge-orders-demo и семь узлов. Нажмите Zoom to Fit. В вашей версии также может быть More actions → Import from File. Не вставляйте файл повторно поверх готовой цепочки.
Manual Trigger запускает две ветки. Верхняя: Test Orders → Split Orders → Input 1 узла Match Customers. Нижняя: Test Customers → Split Customers → Input 2 того же узла. Его выход подключён к Result. Две ветки здесь не условные: при полном запуске обе готовят данные.
Шаг 3. Проверьте список заказов
Дважды щёлкните значок Test Orders. Это Edit Fields, Mode = JSON Output. В поле JSON должен быть такой объект:
{
"orders": [
{
"order_id": "O1",
"customer_id": "C1",
"amount": 1500
},
{
"order_id": "O2",
"customer_id": "C2",
"amount": 2400
},
{
"order_id": "O3",
"customer_id": "C9",
"amount": 800
}
]
}
order_id обозначает заказ, customer_id - ключ клиента, amount - учебную сумму без расчёта налогов или валютных курсов. O3 ссылается на C9, которого намеренно нет в справочнике. Нажмите Execute step: получится один item с массивом из трёх заказов.
Шаг 4. Проверьте справочник клиентов
Откройте Test Customers - второй Edit Fields в режиме JSON Output. Проверьте поле JSON:
{
"customers": [
{
"customer_id": "C2",
"customer_name": "Учебная компания Б",
"segment": "business"
},
{
"customer_id": "C1",
"customer_name": "Учебная компания А",
"segment": "small_business"
},
{
"customer_id": "C3",
"customer_name": "Учебная компания В",
"segment": "business"
}
]
}
Здесь customer_id - тот же ключ, customer_name - вымышленное название, segment - учебный сегмент. C2 стоит раньше C1, а C3 вообще не имеет заказа. Именно поэтому нельзя подставлять компанию по номеру строки. После Execute step получится один item с тремя клиентами.
Шаг 5. Разделите оба массива на записи
У Split Orders, узла Split Out, Fields To Split Out = orders, Include = No Other Fields. У Split Customers такое же устройство, но Fields To Split Out = customers. В обоих Destination Field Name не задан.
Выполните каждый узел через Execute step. На каждом выходе должно быть три items с полями верхнего уровня, а не один item с массивом. Проверьте, что Split Orders подключён к Input 1 Merge, а Split Customers - к Input 2. Обратное подключение поменяет смысл сохранения данных.
Как разделить JSON-массив в n8n
Шаг 6. Настройте объединение по customer_id
Откройте Match Customers, это узел Merge. Проверьте Mode = Combine, Combine By = Matching Fields. Fields To Match Have Different Names выключен, потому что ключ одинаково называется в обоих списках. Fields to Match = customer_id в режиме Fixed. Здесь нужно имя поля, не выражение с его значением.
Output Type = Enrich Input 1. Основой результата становятся заказы из первого входа; совпавшие клиенты второго входа добавляют свои поля. Не выбирайте Position: в наших данных первые строки относятся к разным клиентам. Append тоже не решает задачу обогащения заказа.
Шаг 7. Проверьте сравнение и конфликты полей
В Options Fuzzy Compare выключен, Multiple Matches = Include All Matches. В Clash Handling выбрано When Field Values Clash = Prefer Input 1 Version, Merging Nested Fields = Shallow Merge, Minimize Empty Fields выключен. Если создаёте узел вручную, добавьте соответствующие опции через список внизу Options.
В этой настройке поле заказа имеет приоритет при совпадающем имени. Например, если справочник тоже содержит amount, исходная сумма заказа должна сохраниться. Приоритет одного входа не означает, что его данные верные: для настоящей схемы явно определите, откуда брать каждое поле. Здесь структуры плоские, вложенные объекты не используются.
Include All Matches оставляем намеренно: в исходном справочнике ключи уникальны, а в шаге 10 увидим, как дубль увеличивает результат. Эта опция не проверяет уникальность ключа автоматически.
Шаг 8. Проверьте итоговый флаг
Откройте Result - Edit Fields, Mode = Manual Mapping. Поле customer_found имеет тип Boolean. Его значение работает в режиме Expression:
{{ typeof $json.customer_name === 'string' && $json.customer_name.trim().length > 0 }}
Include Other Input Fields включён, чтобы сохранить заказ и добавленные данные. В Settings не включайте Execute Once. Флаг проверяет только наличие непустого названия, а не правильность найденного клиента. Если название в справочнике пустое, даже совпавший ID даст false: это сознательное ограничение этого простого индикатора.
Шаг 9. Выполните всю цепочку и сверяйте результат
Закройте настройки и нажмите Execute workflow на холсте. Откройте Result → OUTPUT → JSON. В нашем проверенном запуске получено:
[
{
"customer_id": "C1",
"customer_name": "Учебная компания А",
"segment": "small_business",
"order_id": "O1",
"amount": 1500,
"customer_found": true
},
{
"customer_id": "C2",
"customer_name": "Учебная компания Б",
"segment": "business",
"order_id": "O2",
"amount": 2400,
"customer_found": true
},
{
"order_id": "O3",
"customer_id": "C9",
"amount": 800,
"customer_found": false
}
]
Проверьте O1/C1/компанию А/1500 и O2/C2/компанию Б/2400. O3/C9/800 остался без customer_name с customer_found = false. Компания В не добавилась отдельной строкой: она не является заказом первого входа. Итог - три заказа, а не шесть отдельных записей двух списков.
Для дополнительной проверки поменяйте местами C1 и C2 в Test Customers и снова выполните весь workflow. Связи O1 с компанией А и O2 с компанией Б должны сохраниться. Сверяйте ID и поля, а не только число строк. После проверки верните исходный JSON справочника.
Шаг 10. Проверьте дубли ключей
В Test Customers временно замените JSON набором, где к исходным трём клиентам добавлена вторая запись C1:
{
"customers": [
{
"customer_id": "C2",
"customer_name": "Учебная компания Б",
"segment": "business"
},
{
"customer_id": "C1",
"customer_name": "Учебная компания А",
"segment": "small_business"
},
{
"customer_id": "C3",
"customer_name": "Учебная компания В",
"segment": "business"
},
{
"customer_id": "C1",
"customer_name": "Вторая запись C1",
"segment": "duplicate"
}
]
}
Выполните всю цепочку с Include All Matches. Получатся четыре записи: O1 дважды с разными названиями клиента, O2 один раз и O3 без совпадения. Заказ не был создан повторно - он размножился в результате объединения из-за двух совпадений. Если далее суммировать amount, сумма станет ошибочной.
В Options → Multiple Matches временно выберите Include First Match Only и повторите запуск. Получатся три записи, а O1 возьмёт компанию А - первое совпадение этого конкретного набора. Это не выбор самой свежей или достоверной компании. Для производства устраните неоднозначность справочника по явным правилам, а не скрывайте её выбором первой строки.
Верните исходный JSON из шага 4 и Include All Matches. Полный запуск должен снова дать три заказа с исходными связями.
Шаг 11. Проверьте разные типы ключей
Для отдельного теста в Test Orders поставьте:
{"orders":[{"order_id":"T1","customer_id":1,"amount":100},{"order_id":"T2","customer_id":"1","amount":200}]}
В Test Customers поставьте:
{"customers":[{"customer_id":"1","customer_name":"Строковый ключ","segment":"test"}]}
Выполните весь workflow при выключенном Fuzzy Compare. T2 со строковым "1" получит название клиента и true. T1 с числом 1 останется без названия с false. Оба заказа сохранятся; несовпадение типов не должно превращать один заказ в другого. В нашем запуске совпавший T2 появился раньше T1 - не рассчитывайте на исходный порядок после объединения.
Не включайте нечёткое сравнение вслепую. Если ваша система использует строковые ID, приведите данные к согласованному формату до Merge, сохраняя ведущие нули и значимые символы. Пустые ключи, пробелы и права доступа тоже требуют отдельной проверки: эта схема их не валидирует.
Шаг 12. Сравните режимы и восстановите пример
Верните оба исходных JSON из шагов 3 и 4. В Match Customers временно выберите Output Type = Keep Matches; Output Data From = Both Inputs Merged Together. После полного запуска останутся только O1 и O2, а O3 исчезнет из результата, потому что клиента C9 нет. Это ожидаемая работа этого режима, но не наша задача.
Верните Enrich Input 1. Для проверки конфликта временно добавьте в каждую запись Test Customers поле amount со значением 9999. При Prefer Input 1 Version суммы заказов должны остаться 1500, 2400 и 800. Затем удалите учебное поле amount из справочника, вернув JSON шага 4.
Повторите полный запуск с исходными настройками: три заказа, два true, один false, исходные суммы и названия. Схема остаётся ручной и неопубликованной. Это законченный результат упражнения. Пустые потоки, условные ветки If/Switch и SQL Query здесь не проверялись: не переносите этот тест на них без дополнительной проверки.
Если результат отличается
| Симптом | Что проверить | Исправление |
|---|---|---|
| Компания у чужого заказа | Combine By | Matching Fields, не Position |
| Пропал O3 | Output Type | Enrich Input 1 |
| Получились четыре строки | Ключи в справочнике | Проверить дубль C1 |
| В результате только флаг | Result | Include Other Input Fields |
| Число 1 не совпало со строкой | Типы ключа | Согласовать формат до Merge |
| Изменилась сумма заказа | Clash Handling | Prefer Input 1 Version |
Перед подключением настоящих данных
Заказы можно получить из API, а справочник - из другого источника, но сначала проверьте структуры и полноту выгрузок. Одна неполная страница справочника не доказывает, что клиент отсутствует: проверьте пагинацию и фильтры. Match Customers не обращается к базе самостоятельно, он использует только пришедшие items.
Как получить JSON через HTTP Request
Не подключайте к упражнению выставление счетов, платежи или рассылку. Сначала проверьте уникальность order_id, ключей справочника, число строк и контрольные суммы; ошибочные совпадения направляйте на ручную проверку. customer_found не является проверкой личности или разрешением на доступ к документам.
Что проверено редакцией
10 октября 2026 года workflow проверен на n8n 2.42.4. Восемь CLI-сценариев в отдельной тестовой базе: исходный набор, перестановка клиентов, дубли со всеми и первым совпадением, числовой и строковый ключ, Keep Matches, конфликт amount и восстановление. Проверены ID заказов, суммы, названия и флаг customer_found. В локальном редакторе выполнены исходный Enrich Input 1, Keep Matches и восстановление; получены соответственно три, два и три заказа. Новый workflow не публиковался, старые схемы не менялись. Cloud, настоящие API/CRM, пагинация, пустые потоки, условные ветки, SQL Query и вложенные объекты не тестировались. Обложка - редакционная иллюстрация.
Частые вопросы
Как объединить два списка по ID в n8n?
В этом примере заказы подключены к Input 1, клиенты - к Input 2. В Merge выбран Combine → Matching Fields, поле customer_id и Enrich Input 1. На результат влияют тип ключа, дубли и конфликтующие поля, поэтому сверяйте конкретные ID.
Почему заказ без клиента исчез из результата?
В проверке Keep Matches сохранил только O1 и O2. Для сохранения всех заказов мы используем Enrich Input 1. Проверьте также подключение входов: основой этого режима должен быть список заказов.
Почему после Merge стало больше строк?
В справочнике могут быть несколько совпадений для одного ключа. Учебный дубль C1 при Include All Matches дал две строки O1 и увеличил результат до четырёх записей. Это важно проверить до суммирования и любых внешних действий.
Можно ли соединять списки по порядку строк?
Для этой задачи нельзя: клиенты специально расположены в другом порядке, поэтому порядковое соединение перепутает компании. Здесь используем customer_id и дополнительно проверяем перестановку строк справочника.
Нужен ли AI для Merge и что значит customer_found?
AI не нужен: совпадения определяются заданным ключом. customer_found - наш дополнительный Boolean, который проверяет непустое customer_name. Он не подтверждает правильность компании, личность клиента или права на работу с заказом.