Как найти слово с неизвестной частью в 1С и почему полнотекстовый поиск не ищет по произвольной маске

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При работе с базами данных пользователи часто сталкиваются с ситуацией, когда точное написание наименования, фамилии или контрагента неизвестно. Например, неясно, как правильно пишется фамилия: Жеглов, Жезлов или Жезелов. Попытка использовать штатный полнотекстовый поиск с масками вроде Же*лов не даёт результатов. Разберёмся, почему так происходит, какие ограничения существуют у механизм полнотекстового поиска 1С и как реализовать удобный поиск по фрагментам слов.

Ограничения штатного полнотекстового поиска 1С

Механизм полнотекстового поиска в платформе 1С рассчитан на работу со словарем терминов (лемм) и лингвистический анализ целых слов. Из-за особенностей архитектуры полнотекстового индекса существуют следующие правила и ограничения:

  1. Групповой символ «*» (звездочка): Поддерживается только один символ маски, и он должен находиться строго в конце слова. Запрос вида арх* успешно найдет «архив» и «археология», однако запросы вида *лов или Же*лов не работают — маска в начале или середине слова механизмом не обрабатывается.
  2. Ограничение на количество вариантов подстановки: Если ввести слишком короткую строку с маской на конце (например, Же*), платформа попытается подставить все подходящие слова из индекса. Если таких слов окажется больше допустимого лимита (300 терминов), система выдаст ошибку о слишком большом количестве результатов или перестанет отвечать.
  3. Нечеткий поиск (символы «#» или «~»): Позволяет искать слова с опечатками с учетом расстояния Левенштейна (количество замен, удалений или вставок). Например, запрос Система#1 найдет «систама» или «сивтема». Однако нечеткий поиск работает только от целиком указанного слова, а не от обрезка с маской.

Решение 1: Использование запросов 1С с оператором ПОДОБНО

Если требуется найти записи, содержащие фрагменты в любой части строки, наиболее надежным решением является использование языка запросов 1С с оператором ПОДОБНО и спецсимволом % (подстановочный знак для произвольного количества символов).

Рассмотрим пример запроса, который ищет наименования, начинающиеся на «Же» и заканчивающиеся на «лов», по нескольким справочникам одновременно:


ВЫБРАТЬ
    Ссылка КАК Ссылка,
    Наименование КАК Наименование
ИЗ
    Справочник.Партнеры
ГДЕ
    Наименование ПОДОБНО "%Же%лов%"

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    Ссылка,
    Наименование
ИЗ
    Справочник.Контрагенты
ГДЕ
    Наименование ПОДОБНО "%Же%лов%"

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    Ссылка,
    Наименование
ИЗ
    Справочник.КонтактныеЛицаПартнеров
ГДЕ
    Наименование ПОДОБНО "%Же%лов%"

Решение 2: Динамический поиск по подстрокам (слогам)

Для создания удобного интерфейса подбора, когда пользователь вводит словесные фрагменты через пробел (например, Же лов), можно программно сформировать запрос с условиями ПОДОБНО для каждого введенного подслова.

Разберем по шагам алгоритм формирования такого запроса:

  1. Разбиваем введенную пользователем строку в массив подстрок по разделителю пробел.
  2. Обходим массив в цикле и формируем динамические условия запроса, соединяя их логическим И.
  3. Устанавливаем параметры запроса с добавлением знаков % с обеих сторон каждого слога.

Посмотрим на пример реализации данного подхода на языке 1С:


МассивКлючевыхСлов = СтрРазделить(СтрокаПоиска, " ", ЛОЖЬ);
КоличествоКлючевыхСлов = МассивКлючевыхСлов.Количество();

Запрос = Новый Запрос;
УсловиеПоиска = "";

Для инд = 0 По КоличествоКлючевыхСлов - 1 Цикл
    СтрКлючевоеСлово = СокрЛП(МассивКлючевыхСлов[инд]);
    Если ПустаяСтрока(СтрКлючевоеСлово) Тогда
        Продолжить;
    КонецЕсли;
    
    УсловиеПоиска = УсловиеПоиска + " И СпрНоменклатура.Наименование ПОДОБНО &ПодстрокаПоиска" + Строка(инд);
    Запрос.УстановитьПараметр("ПодстрокаПоиска" + Строка(инд), "%" + СтрКлючевоеСлово + "%");
КонецЦикла;

ТекстЗапроса = 
"ВЫБРАТЬ
|	СпрНоменклатура.Ссылка КАК Номенклатура,
|	СпрНоменклатура.Наименование КАК Наименование,
|	СпрНоменклатура.Артикул КАК Артикул
|ИЗ
|	Справочник.Номенклатура КАК СпрНоменклатура
|ГДЕ
|	СпрНоменклатура.ЭтоГруппа = ЛОЖЬ" + УсловиеПоиска;

Запрос.Текст = ТекстЗапроса;
РезультатЗапроса = Запрос.Выполнить();

Такой подход избавляет пользователей от необходимости запоминать специальные управляющие символы и позволяет быстро находить данные по нескольким фрагментам слов одновременно.

← На главную