База знаний GetMyBot

Поля и объединение списков

Как извлечь вложенные поля ответа сервиса, рассчитать значение для каждой строки и соединить два списка по общему коду.

На этой странице

Сервис заказов вернул имя клиента внутри customer, а стоимость нужно посчитать из цены и количества. В другом списке лежат названия занятий, к которым относятся заказы. Эти данные можно подготовить двумя действиями:

  • Преобразовать поля списка (list_map) создаёт нужные поля у каждой строки.
  • Соединить списки (list_join) добавляет данные из второго списка по совпадающему ключу.

Оба действия работают с уже загруженными данными. Они не запрашивают внешние сервисы и не изменяют записи коллекции. Для фильтрации, сортировки и подсчёта используйте другие действия над списками.

Получить имя и рассчитать стоимость

Допустим, предыдущий запрос сохранил под именем orders такой массив:

[
  {"id":"o1","customer":{"name":"Анна"},"price":1500,"quantity":2},
  {"id":"o2","price":2000,"quantity":1}
]

В Преобразовать поля списка выберите источник orders. Добавьте два поля результата:

Новое полеОперацияОткуда взять значение
guest_nameКопироватьПуть customer.name; значение по умолчанию Без имени
amountУмножитьПути price и quantity

Сохраните результат под именем prepared_orders. Технические параметры:

{
  "source": "orders",
  "fields": [
    {"as":"guest_name","op":"copy","path":"customer.name","default":"Без имени"},
    {"as":"amount","op":"multiply","paths":["price","quantity"]}
  ],
  "keep_fields": false,
  "save_to_ctx": "prepared_orders"
}

В prepared_orders.rows ожидаются две строки:

[
  {"guest_name":"Анна","amount":3000},
  {"guest_name":"Без имени","amount":2000}
]

Если нужны также исходные id, price и quantity, включите сохранение остальных полей (keep_fields=true). Без этой настройки в обычной строке останутся только созданные поля. Служебные поля настоящего результата поиска сохраняются отдельно и не заменяются вашими вычислениями.

Доступные операции

ОперацияПараметр opПример применения
Копировать полеcopyВзять customer.name
Задать значениеliteralДобавить source="catalog" каждой строке
Соединить текстconcatСоединить несколько скалярных полей
СложитьaddСложить стоимость и доставку
ВычестьsubtractВычесть скидку
УмножитьmultiplyЦена × количество
РазделитьdivideСумма / число участников

Для копирования укажите path, для нескольких операндов – paths, для постоянного значения – value. Каждый расчёт читает исходную строку. Поле, созданное выше в том же действии, не становится входом следующего поля: для такого расчёта добавьте ещё одно действие.

Арифметика выполняется в порядке перечисления операндов. Например, subtract с тремя путями означает «первое минус второе минус третье». Числа остаются точными: 0.1 × 3 даёт 0.3. Деление округляется до 12 знаков после запятой; деление на ноль и выход за числовые ограничения дают ошибку.

Необязательный type преобразует результат к text, number или boolean. Числовая строка "1500" может стать числом. Для логического преобразования подходят логическое значение либо строки "true" и "false". Неверные значения не превращаются незаметно в ноль или false.

Вложенные пути и пустые значения

Путь customer.name выбирает имя из объекта customer. Путь items.0.id выбирает ID первого элемента массива; отсчёт начинается с нуля.

Если в исходном объекте есть буквальный ключ с точкой, например "customer.name", используйте JSON Pointer /customer.name. В JSON Pointer символ / внутри ключа записывается как ~1, а ~ как ~0.

Значение по умолчанию применяется, когда поле отсутствует. Явное null считается присутствующим значением и не заменяется автоматически. Копирование отсутствующего поля без значения по умолчанию даёт null; числовая операция над отсутствующим, пустым или ошибочным числом завершается ошибкой.

Добавить к заявкам названия занятий

Пусть первый список bookings содержит заявки:

[
  {"id":"b1","class_code":"wc","guest":"Анна"},
  {"id":"b2","class_code":"clay","guest":"Борис"},
  {"id":"b3","class_code":"photo","guest":"Вера"}
]

Во втором списке classes находятся занятия:

[
  {"code":"wc","name":"Акварель"},
  {"code":"clay","name":"Лепка"}
]

Добавьте Соединить списки: слева bookings, справа classes, ключи class_code и code. Оставьте левое объединение, политику неоднозначности «Ошибка» и префикс правых полей details_. Сохраните как joined_bookings.

{
  "source": "bookings",
  "right_source": "classes",
  "left_key": "class_code",
  "right_key": "code",
  "mode": "left",
  "multiple": "error",
  "right_prefix": "details_",
  "save_to_ctx": "joined_bookings"
}

В результате первая строка содержит guest="Анна" и details_name="Акварель", вторая – guest="Борис" и details_name="Лепка". Заявка Веры остаётся без добавленных полей: занятия photo во втором списке нет.

Префикс защищает от одинаковых имён полей. Например, с префиксом class_ правое поле code получило бы имя class_code, которое уже есть слева. Действие сообщит о конфликте, поэтому выберите другой префикс, как details_ в примере.

Служебные поля _record_id, _score и _match_type правого результата не добавляются: строка результата по-прежнему относится к левой записи. Если нужен ID правой записи, перед объединением скопируйте её _record_id действием Преобразовать поля списка в обычное поле, например class_record_id. После объединения оно будет доступно с выбранным префиксом, например details_class_record_id.

Что делать с отсутствующими и повторяющимися ключами

НастройкаПоведение
Левое объединение (mode=left)Оставляет все строки первого списка, даже без совпадения
Только совпадения (mode=inner)Оставляет строки, для которых нашлась запись справа
Ошибка при нескольких совпадениях (multiple=error)Не выбирает неоднозначную запись молча
Первое совпадение (multiple=first)Берёт первую подходящую строку правого списка
Все совпадения (multiple=all)Создаёт отдельную строку для каждого совпадения

В режиме all число строк может вырасти. Например, две заявки и три записи справочника с одним кодом дадут шесть строк. Такой результат подчиняется общим ограничениям объёма.

Отсутствующие ключи и значения null не совпадают друг с другом. Пустая строка "" считается обычным текстовым ключом и может совпасть с другой пустой строкой; если это нежелательно, заранее отфильтруйте такие строки. Тип ключа тоже важен: число 1 отличается от строки "1". Объекты и массивы не подходят как ключи соединения. Числовые значения сравниваются точно, без потери больших ID; идентификаторы сервисов обычно удобнее хранить строками.

Порядок первого списка сохраняется. Если выбраны все совпадения, строки второго списка добавляются в их исходном порядке. Поэтому «Первое совпадение» имеет смысл только тогда, когда вы заранее знаете порядок правого списка.

Полнота, ограничения и проверка

На каждый вход и результат действует предел 10 000 строк. Для объединения размер двух входов вместе ограничен 16 МиБ; выход также ограничен по размеру. Допустимо до 256 настроек полей. Превышение вызывает ошибку, а не скрытое удаление лишних строк.

Дополнительно ограничена вычислительная работа: не больше 1 000 000 условных операций на действие. Учитываются строки, количество настраиваемых полей, операнды и глубина путей; для объединения также учитывается число создаваемых строк и полей. Если преобразование слишком сложное, сократите входной список, ненужные поля или число операндов. Ограничение проверяется до большого расчёта. Проверка также прекращается при отмене запроса.

В предел 16 МиБ результата входит небольшой резерв 512 байт для служебных полей. Поэтому строка, занимающая почти весь предел, может не поместиться вместе с результатом операции. Большие промежуточные строки и неоднозначное размножение результатов ограничиваются до их накопления в памяти.

Если любой исходный результат был неполным, объединённый результат остаётся неполным. Действие не может узнать о совпадении, которое не было загружено из правого источника. Не показывайте отсутствие совпадения как доказательство отсутствия записи во всей базе.

Предварительная проверка принимает буквальные JSON-данные. Она не запускает реакцию, не вызывает внешние сервисы и не записывает изменения в коллекции. Для всей несохранённой цепочки используйте проверку черновика на учебных данных: получение данных → преобразование → подготовка кнопки или сообщения. После сохранения отдельно проверьте путь через подключённого бота и канал. Этот запуск выполняет сохранённые действия, включая обращения к сервисам и изменения записей.

Для ручной проверки используйте четыре случая: обычная строка, отсутствующее вложенное поле, повтор ключа справочника и неполный исходный список. В результате проверьте порядок, количество строк и признак полноты.

Связанные материалы: свойства списков и итоги, коллекции, практика работы с каталогом.