При администрировании, чистке или переносе данных в информационных базах 1С:Предприятие 8 перед разработчиком часто возникает задача: оперативно найти все объекты (справочники, документы, регистры), которые содержат определенную текстовую строку. Например, это необходимо для удаления «мусорных» элементов или поиска связанных сущностей при ручной очистке базы данных.
В рамках этой статьи мы подробно разберем, как решить эту задачу эффективно. Мы проанализируем различные подходы — от стандартного полнотекстового поиска платформы до написания собственного алгоритма обхода метаданных с динамическим построением запросов. Выясним, почему некоторые популярные решения могут быть опасны для производительности СУБД, и выработаем оптимальный план действий.
Самым быстрым и технологически правильным способом найти подстроку во всех объектах базы данных является использование встроенного механизма полнотекстового поиска (ППД). Он работает в тысячи раз быстрее обычных запросов, так как использует заранее построенный и оптимизированный индекс СУБД, избегая полного сканирования таблиц.
Давайте разберем по шагам, как реализовать такой поиск программно.
Шаг 1. Проверка актуальности и обновление индекса
Перед началом поиска крайне важно убедиться, что индекс полнотекстового поиска актуален. Если в системе недавно происходили изменения данных, индекс необходимо обновить, иначе новые или измененные объекты просто не попадут в результаты выдачи.
Если Не ПолнотекстовыйПоиск.ИндексАктуален() Тогда
// Истина — запускает слияние индексов, Ложь — обновление выполняется за один проход
ПолнотекстовыйПоиск.ОбновитьИндекс(Истина, Ложь);
КонецЕсли;
Шаг 2. Создание списка поиска и ограничение области
Для выполнения поиска мы используем объект ПолнотекстовыйПоиск.СоздатьСписок. Обратите внимание: символ "*" в конце поисковой строки позволяет искать слова, которые начинаются с указанной подстроки.
// Создаем список поиска с ограничением на количество выводимых результатов (например, 100 элементов)
СписокПоиска = ПолнотекстовыйПоиск.СоздатьСписок("Подстрока1*", 100);
СписокПоиска.ПолучатьОписание = Истина; // Требуется для получения текстового описания найденных объектов
// При необходимости мы можем программно ограничить область поиска конкретными метаданными
МассивОбластей = Новый Массив;
МассивОбластей.Добавить(Метаданные.Справочники.Номенклатура);
МассивОбластей.Добавить(Метаданные.Документы.ПоступлениеТоваровУслуг);
СписокПоиска.ОбластьПоиска = МассивОбластей;
// Выполняем поиск первой порции результатов
СписокПоиска.ПерваяЧасть();
Шаг 3. Обработка результатов поиска
Результатом выполнения метода является коллекция элементов, где свойство Значение содержит непосредственную ссылку на найденный объект базы данных.
Для Каждого ЭлементИзСписка Из СписокПоиска Цикл
СсылкаНаОбъект = ЭлементИзСписка.Значение;
Сообщить("Найден объект: " + СсылкаНаОбъект + " (Тип: " + СсылкаНаОбъект.Метаданные().Имя + ")");
КонецЦикла;
Преимущества метода:
Ограничения метода:
Полнотекстовый поиск (значение Использовать). По умолчанию для справочников и документов оно включено, но для некоторых служебных реквизитов или регистров сведений может быть деактивировано разработчиками конфигурации.Если вы работаете с типовой конфигурацией (например, «1С:Розница», «1С:Управление торговлей» или «1С:ERP»), то Библиотека Стандартных Подсистем (БСП) уже содержит всё необходимое для решения этой задачи.
Интерактивный вариант:
Вы можете воспользоваться стандартной обработкой БСП. Для этого выполните следующие действия:
Программный вариант через БСП:
Если вам требуется реализовать поиск программно в своей обработке, используйте готовый программный интерфейс общего модуля ПолнотекстовыйПоискСервер:
ПараметрыПоиска = ПолнотекстовыйПоискСервер.ПараметрыПоиска();
ПараметрыПоиска.СтрокаПоиска = "Подстрока1";
// Метод вернет структуру с результатами полнотекстового поиска
Результат = ПолнотекстовыйПоискСервер.ВыполнитьПолнотекстовыйПоиск(ПараметрыПоиска);
Что делать, если полнотекстовый поиск в базе отключен или интересующий вас реквизит исключен из индексации? В этом случае единственным решением остается программный перебор метаданных конфигурации и динамическое построение запросов СУБД с оператором ПОДОБНО.
Рассмотрим пример реализации такого алгоритма для поиска по наименованию и строковым реквизитам справочников:
Для Каждого СправочникМетаданные Из Метаданные.Справочники Цикл
// Массив для хранения имен строковых полей текущего справочника
ПоляДляПоиска = Новый Массив;
// Проверяем длину наименования справочника
Если СправочникМетаданные.ДлинаНаименования > 0 Тогда
ПоляДляПоиска.Добавить("Наименование");
КонецЕсли;
// Перебираем реквизиты справочника и ищем строковые типы
Для Каждого Реквизит Из СправочникМетаданные.Реквизиты Цикл
Если Реквизит.Тип.СодержитТип(Тип("Строка")) Тогда
ПоляДляПоиска.Добавить(Реквизит.Имя);
КонецЕсли;
КонецЦикла;
// Если строковые поля найдены, строим динамический запрос
Если ПоляДляПоиска.Количество() > 0 Тогда
ТекстУсловий = "";
Для Каждого ИмяПоля Из ПоляДляПоиска Цикл
Если ЗначениеЗаполнено(ТекстУсловий) Тогда
ТекстУсловий = ТекстУсловий + " ИЛИ ";
КонецЕсли;
ТекстУсловий = ТекстУсловий + "ТаблицаИсточник." + ИмяПоля + " ПОДОБНО &ШаблонПоиска";
КонецЦикла;
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ Ссылка " +
"ИЗ Справочник." + СправочникМетаданные.Имя + " КАК ТаблицаИсточник " +
"ГДЕ " + ТекстУсловий;
Запрос.УстановитьПараметр("ШаблонПоиска", "%Подстрока1%");
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Сообщить("Найдено совпадение в справочнике " + СправочникМетаданные.Имя + ": " + Выборка.Ссылка);
КонецЦикла;
КонецЕсли;
КонецЦикла;
Внимание! Критическая опасность метода динамических запросов:
Конструкция ПОДОБНО "%Текст%" (с процентом в начале строки поиска) заставляет СУБД игнорировать стандартные индексы таблиц. Это приводит к так называемому полному сканированию таблиц (Table Scan / Clustered Index Scan).
Если вы запустите подобный перебор на работающей базе данных с большим объемом документов или записей регистров сведений, это приведет к следующим последствиям:
rphost может аварийно завершиться из-за превышения лимитов оперативной памяти.Золотое правило: динамический поиск через ПОДОБНО по всем метаданным можно запускать исключительно на копии базы данных или в нерабочее время (ночью), когда в базе полностью отсутствуют активные пользователи.
Проанализируем развитие механизмов поиска в платформе 1С. Фирма «1С» активно развивает инструменты глобального поиска:
Ctrl+Shift+F в режиме Предприятия). Он выполняет сквозной полнотекстовый поиск по всем данным конфигурации прямо из коробки и не требует написания программного кода.Подведем итог. Для качественного и безопасного поиска подстроки воспользуемся следующим алгоритмом принятия решений:
ПолнотекстовыйПоиск. Обязательно выполните предварительную актуализацию индекса методом ПолнотекстовыйПоиск.ОбновитьИндекс().ПОДОБНО. Но выполняйте эту процедуру только на резервной копии базы данных, чтобы не парализовать работу пользователей.