В процессе разработки часто возникает задача реализовать поиск по списку текстовых значений, используя оператор ПОДОБНО. Однако при попытке объединить логику массивов и шаблонов поиска разработчики сталкиваются с ограничениями платформы 1С:Предприятие. Давайте разберем, почему «простой» путь не работает и какие архитектурные подходы позволят реализовать такую функциональность без потери производительности.
Многие разработчики задаются вопросом: можно ли передать массив масок в условие ГДЕ Реквизит ПОДОБНО (&МассивМасок)? Ответ однозначен — нет, это невозможно. Платформа 1С требует, чтобы операндом в операторе ПОДОБНО выступал либо строковый литерал, либо параметр запроса, содержащий готовую строку шаблона. Использование динамически сформированных строк или конкатенации прямо в тексте запроса категорически не рекомендуется стандартизацией разработки 1С.
Основная причина запрета заключается в обеспечении кроссплатформенности. Разные СУБД (например, MS SQL Server и PostgreSQL) по-разному интерпретируют символы шаблонов (%, _, [ ]). Формирование шаблона на уровне СУБД через конкатенацию может привести к непредсказуемым результатам, ошибкам в работе индексов и различиям в выдаче данных в файловом и клиент-серверном вариантах.
Если перед вами стоит задача искать по «тысячам трекеров» или другим идентификаторам, простые переборы через ИЛИ приведут к деградации производительности. Рассмотрим методы, которые помогут заставить поиск «летать».
Один из наиболее производительных способов — создание временной таблицы, содержащей ваши маски. Вместо попытки «впихнуть» массив в ПОДОБНО, мы делаем следующее:
ТаблицаМасок с колонкой Шаблон.
ВЫБРАТЬ
Т.Ссылка
ИЗ
Документ.МойДокумент КАК Т
ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_Маски КАК Маски
ПО Т.МойРеквизит ПОДОБНО Маски.Шаблон
Важное примечание: Хотя этот метод технически позволяет использовать оператор ПОДОБНО в условии соединения, помните, что наличие символа % в начале шаблона (например, %123) делает невозможным использование индексов, что приведет к полному сканированию таблицы (Full Table Scan).
В некоторых случаях, согласно теории оптимизации запросов, использование оператора ОБЪЕДИНИТЬ (или ОБЪЕДИНИТЬ ВСЕ) работает эффективнее, чем громоздкое условие ГДЕ А ИЛИ Б ИЛИ В. Это позволяет оптимизатору запросов СУБД обрабатывать каждую ветку по отдельности.
ВЫБРАТЬ Данные ИЗ Регистр КАК Р ГДЕ Р.Поле ПОДОБНО &Шаблон1
ОБЪЕДИНИТЬ
ВЫБРАТЬ Данные ИЗ Регистр КАК Р ГДЕ Р.Поле ПОДОБНО &Шаблон2
...
Однако этот метод подходит только для небольшого количества шаблонов. При поиске по сотням значений этот подход станет неэффективным.
Если поиск — это ваш основной сценарий работы, значит, текущая модель данных не адаптирована под него. Рассмотрите следующие рекомендации:
=), а не по строковым шаблонам.1С предоставляет встроенный механизм ПолнотекстовыйПоиск. Он индексирует текстовые данные заранее, что позволяет искать части слов и шаблоны на порядки быстрее, чем оператор ПОДОБНО.MD5). Поиск по индексу хеша работает практически мгновенно.При организации поиска для пользователей разделите задачу на два этапа:
= или оператор В). Это самый быстрый путь, который покроет 90% корректных запросов.ПОДОБНО с шаблонами.Помните, что архитектурно правильным решением является валидация ввода. Если пользователи «вносят всякую хрень» в поле, ограничьте их возможности через РегулярныеВыражения или маски ввода, чтобы в систему попадали только данные в корректном формате. Это избавит вас от необходимости изобретать сложные алгоритмы для поиска по «кривым» строкам в будущем.