Поиск данных в 1С:Предприятии 8.3 — от строки поиска в списке до своего поискового движка
Содержание
Чтобы реализовать поиск в 1С, чаще всего не нужно писать код. Для поиска по одному списку хватает строки поиска и отборов формы. Для поиска «по всей базе» — встроенного полнотекстового поиска: его включают в режиме Предприятия, отмечают нужные объекты в конфигурации и настраивают регламентное обновление индекса.
Частое заблуждение — что быстрый поиск делается запросом с ПОДОБНО "%текст%". На справочнике в 500 записей он работает. На таблице в миллион строк такой запрос читает её целиком, потому что СУБД не может использовать индекс при маске, начинающейся с %. Методы поиска в 1С различаются по скорости в сотни раз, поэтому выбирать их нужно под объём данных и сценарий.
Всё ниже относится к платформе 8.3 (интерфейс «Такси») и не зависит от конфигурации. Где упоминаются формы БСП, это типовые БП 3.0, ЗУП 3.1, УТ 11 и другие решения на Библиотеке стандартных подсистем.
Отборы и строка поиска в списках: что работает без программирования
Начинать стоит с того, что платформа даёт любому пользователю.
Строка поиска списка
В правом верхнем углу формы списка есть поле поиска. Пользователь вводит фрагмент — список фильтруется по всем видимым колонкам.
- 🔍
Ctrl+Fставит курсор в строку поиска. - 🎯
Alt+Fоткрывает расширенный поиск: можно выбрать колонку и способ сравнения (по началу строки, по любой части, точное совпадение). - ⌨️ Если начать печатать в выделенной колонке, сработает быстрый поиск по ней.
Строка поиска удобна, но на больших списках с поиском «по любой части» она работает медленно — по той же причине, что и ПОДОБНО "%…%".
Отборы и настройки списка
Для повторяющихся условий лучше отбор. В меню Ещё формы списка откройте настройку списка, вкладку «Отбор». Там можно задать условие по любому реквизиту, в том числе по реквизитам связанных объектов через точку («Контрагент.ИНН»).
Настройки сохраняются у пользователя. Бухгалтер один раз делает отбор «Не проведён» в журнале документов и больше его не собирает.
Ввод по строке в полях
Поиск при наборе в поле ввода (выбираете контрагента в документе, печатаете «Ром», получаете «Ромашка ООО») настраивается в конфигураторе у самого справочника:
| Свойство объекта | Что даёт |
|---|---|
| «Ввод по строке» | Список полей, по которым ищется введённый текст (Наименование, Код, ИНН — если добавлен) |
| «Способ поиска строки при вводе по строке» | Начало строки или любая часть строки |
| «Полнотекстовый поиск при вводе по строке» | Подбор через полнотекстовый индекс вместо обычного запроса |
Добавить ИНН в «Ввод по строке» — дешёвый способ ускорить работу менеджеров: контрагента находят по 10 цифрам, а не по названию с кавычками и формой собственности.
Полнотекстовый поиск в 1С: включение, индекс и язык запросов
Полнотекстовый поиск (ППД) — механизм платформы, который строит отдельный индекс по текстовым данным базы и ищет по словам с учётом морфологии. Запрос «договор поставки» найдёт и «договора поставок».
Где хранится индекс
Индекс — это не таблица СУБД, а набор файлов:
- 📁 в файловой базе — в папке
1Cv8FTxtвнутри каталога базы; - 🖥 в клиент-серверной — на сервере 1С, в каталоге данных кластера, в подкаталоге информационной базы.
Отсюда практичное следствие: индекс не попадает в выгрузку .dt и не переносится при восстановлении базы из бэкапа СУБД. После переноса его строят заново.
Шаг 1. Отметить объекты в конфигурации
У каждого справочника, документа, регистра и у каждого их реквизита есть свойство «Полнотекстовый поиск» со значениями «Использовать» и «Не использовать». По умолчанию в новых объектах оно включено.
Выключайте его там, где искать нечего: служебные регистры, реквизиты-флаги, технические таблицы. Каждый лишний объект раздувает индекс и удлиняет его обновление.
Шаг 2. Разрешить поиск в базе
В типовых конфигурациях на БСП это делается в Администрирование → Общие настройки, в группе настроек полнотекстового поиска. Там же видна дата актуальности индекса и кнопки обновления.
В конфигурации без БСП то же делает одна строка кода на сервере:
ПолнотекстовыйПоиск.УстановитьРежимПолнотекстовогоПоиска(РежимПолнотекстовогоПоиска.Разрешить);
Шаг 3. Настроить обновление индекса
Индекс не обновляется сам в момент записи объекта. Изменённые данные попадают в очередь, а в индекс — при вызове обновления. В БСП для этого два регламентных задания: обновление индекса (часто, порциями) и слияние индекса (раз в сутки, ночью).
| Операция | Как часто | Зачем |
|---|---|---|
| Обновление порциями | каждые 1–15 минут | новые данные быстро становятся доступны для поиска |
| Слияние индексов | раз в сутки, вне рабочего времени | объединяет мелкие части индекса, поиск становится быстрее |
| Полная очистка и перестроение | по необходимости | после переноса базы, при подозрении на повреждение |
Язык поисковых запросов
Пользователи часто не знают, что строка полнотекстового поиска понимает операторы:
- ➕
договор И поставка— оба слова (пробел работает так же); - 🔀
счёт ИЛИ инвойс— любое из слов; - ➖
договор НЕ аренда— исключить слово; - ✳️
ромаш*— слова, начинающиеся с «ромаш»; - 🧩
"акт сверки"— точная фраза; - 🔤
#ромашко— нечёткий поиск, найдёт слово с опечаткой.
После восстановления базы из резервной копии СУБД или загрузки .dt индекс нужно построить заново — иначе поиск вернёт пустой или устаревший результат.
Как ускорить поиск в 1С на больших объёмах данных
Когда в базе миллионы строк, решает не способ вызова, а то, сможет ли СУБД использовать индекс.
Индексирование реквизитов
У реквизита справочника или документа есть свойство «Индексировать»:
- «Не индексировать» — по умолчанию;
- «Индексировать» — создаётся индекс по полю;
- «Индексировать с доп. упорядочиванием» — индекс включает поле упорядочивания, полезно для динамических списков с сортировкой.
Индексируйте поля, по которым регулярно ищут на равенство: ИНН, артикул, штрихкод, внешний идентификатор из обмена. Индекс на каждое поле подряд замедляет запись и раздувает базу.
Правила для запросов поиска
| Приём | Быстро | Медленно |
|---|---|---|
| Сравнение на равенство по индексированному полю | ГДЕ Т.ИНН = &ИНН | — |
| Маска по началу | ПОДОБНО "Ром%" | — |
| Маска по любой части | — | ПОДОБНО "%маш%" — полный просмотр |
| Отбор в параметрах виртуальной таблицы | Остатки(, Номенклатура = &Товар) | условие ГДЕ после соединения |
| Ограничение выборки | ВЫБРАТЬ ПЕРВЫЕ 50 | выборка всего и фильтр в коде |
| Поиск по реквизиту через точку | при небольших таблицах | через составной тип — платформа делает соединение с каждой таблицей типа |
Для поиска по части слова в большой таблице правильный путь — полнотекстовый поиск, а не ПОДОБНО. Если ППД не подходит, отдельный регистр сведений
с нормализованной строкой (без кавычек, «ООО», пробелов, в верхнем регистре) и индексом по ней даёт поиск по началу нормализованного значения.
Добавление индекса или нового реквизита — это изменение структуры. Обновление конфигурации базы данных потребует монопольного доступа, а на большой таблице реструктуризация может идти долго. Планируйте её на нерабочее время.
Проверить, что именно тормозит
Перед оптимизацией замерьте. Включите замер производительности в меню отладки конфигуратора, выполните поиск и посмотрите, какая строка занимает время. Для серверной базы полезен технологический журнал с событием DBMSSQL или DBPOSTGRS — он покажет текст запроса к СУБД и длительность.
Программная реализация поиска в коде конфигурации
Поиск из кода нужен для обработок загрузки, обменов, своих форм поиска. Методы выбирайте от простого к сложному.
Методы менеджеров
Для одиночного поиска хватает встроенных методов менеджера справочника:
Контрагент = Справочники.Контрагенты.НайтиПоРеквизиту("ИНН", ИННИзФайла);
Если Контрагент.Пустая() Тогда
// создаём нового или пишем в протокол
КонецЕсли;
НайтиПоКодуиНайтиПоНаименованию— по стандартным реквизитам; у второго есть параметр точного соответствия.НайтиПоРеквизитувозвращает первую найденную ссылку. Если ИНН повторяется у двух элементов, вы молча получите одну из них.
Для массовой загрузки (тысячи строк из файла) не вызывайте НайтиПоРеквизиту в цикле. Один запрос с отбором ГДЕ ИНН В (&СписокИНН) и соответствие «ИНН → ссылка» работает на порядок быстрее.
Свой поиск через полнотекстовый индекс
Пример серверной процедуры, которая ищет строку по всей базе и возвращает таблицу результатов:
&НаСервереБезКонтекста
Функция НайтиВБазе(СтрокаПоиска)
Результат = Новый ТаблицаЗначений;
Результат.Колонки.Добавить("Ссылка");
Результат.Колонки.Добавить("Объект");
Результат.Колонки.Добавить("Описание");
Если ПолнотекстовыйПоиск.ПолучитьРежимПолнотекстовогоПоиска()
<> РежимПолнотекстовогоПоиска.Разрешить Тогда
Возврат Результат;
КонецЕсли;
Список = ПолнотекстовыйПоиск.СоздатьСписок(СтрокаПоиска, 50);
Список.ПерваяЧасть();
Для Каждого Элемент Из Список Цикл
Строка = Результат.Добавить();
Строка.Ссылка = Элемент.Значение;
Строка.Объект = Элемент.Метаданные.Синоним;
Строка.Описание = Элемент.Описание;
КонецЦикла;
Возврат Результат;
КонецФункции
Что стоит знать о списке результатов:
- 📄 Второй параметр
СоздатьСписок— размер порции. Следующие порции получают методомСледующаяЧасть(). - 🔢
ПолноеКоличество()возвращает общее число найденного — его выводят в форме как «найдено 1 248». - 🚧
СлишкомМногоРезультатов()возвращает Истина, если запрос слишком общий. Попросите пользователя уточнить строку, а не листать тысячи результатов.
Обновление индекса из кода
Если регламентных заданий БСП нет, напишите своё:
Процедура ОбновитьИндексППД() Экспорт
// Слияние = Ложь, Порциями = Истина
ПолнотекстовыйПоиск.ОбновитьИндекс(Ложь, Истина);
КонецПроцедуры
Процедура СлитьИндексППД() Экспорт
ПолнотекстовыйПоиск.ОбновитьИндекс(Истина);
КонецПроцедуры
ПолнотекстовыйПоиск.ИндексАктуален() и ДатаАктуальности() пригодятся, чтобы показать пользователю предупреждение: «индекс обновлён в 10:42, свежие документы могут не найтись».
Поиск по конфигурации и ссылкам: инструменты разработчика
Отдельная задача — найти что-то не в данных, а в самой конфигурации или найти, где используется объект.
- 🧭 В конфигураторе
Ctrl+Fищет в текущем модуле,Ctrl+Shift+F— глобальный поиск по всем модулям, формам, макетам и свойствам. - 🔗 Команда «Поиск ссылок на объект» в контекстном меню дерева метаданных покажет, где используется реквизит, общий модуль или роль.
- 🗃 В режиме Предприятия обработка «Поиск ссылок на объекты» (из меню «Все функции», раздел стандартных) показывает, в каких документах и регистрах встречается конкретный элемент. Без неё не удалить контрагента , который «где-то используется».
- 👯 В типовых конфигурациях на БСП есть обработка поиска и удаления дублей:
Администрирование → Обслуживание → Корректировка данных. Она ищет похожие элементы по наименованию и реквизитам и переносит ссылки на оставляемый элемент.
Объединение дублей перезаписывает документы, где был удаляемый элемент. Сделайте резервную копию и запускайте его, когда в базе мало пользователей: перезапись тысяч документов создаёт блокировки.
Интеграция 1С с внешним поисковым движком
Встроенный ППД закрывает большинство задач. Внешний движок (Elasticsearch, OpenSearch, Manticore) берут, когда нужно:
- 📚 искать по содержимому сотен тысяч вложенных файлов;
- 🏷 ранжирование по релевантности, синонимы, подсказки «вы имели в виду»;
- 🌐 общий поиск по 1С и сайту или нескольким базам сразу;
- ⚡ снять нагрузку поиска с сервера 1С.
Схема интеграции
- Регистрация изменений. Изменённые объекты попадают в план обмена или в регистр-очередь при записи. Подписка на событие
ПриЗаписиздесь удобнее правки модулей объектов. - Выгрузка. Регламентное задание раз в минуту берёт порцию из очереди, формирует JSON через
ЗаписьJSONи отправляет его в движок черезHTTPСоединение(в Elasticsearch — пакетной операцией_bulk). - Поиск. Форма поиска в 1С отправляет запрос в движок по HTTP, получает список идентификаторов (
УникальныйИдентификаторссылки) и превращает их обратно в ссылки черезПолучитьСсылку. - Права. Движок не знает про роли 1С. Либо храните в документе индекса признаки доступа (организация, подразделение) и фильтруйте по ним, либо проверяйте права в 1С уже по полученным ссылкам.
Храните в индексе только то, что нужно для поиска и вывода строки результата: представление, дату, номер, ключевые реквизиты. Полный объект берите из 1С по ссылке — так не возникнет расхождения данных.
Адрес и учётные данные движка держите в константах или защищённом хранилище, а не в тексте модуля.
Частые ошибки при организации поиска
- ❌ Свежий документ не находится полнотекстовым поиском. Индекс не обновился: регламентное задание отключено или выполняется редко. Проверьте дату актуальности индекса. В файловой базе регламентные задания выполняются только при открытом клиенте, если нет отдельного механизма запуска.
- ❌ После переноса базы поиск ничего не находит. Индекс остался на старом сервере или в старой папке. Очистите и постройте индекс заново.
- ❌ Индекс растёт до десятков гигабайт. Включён поиск по всем объектам, включая служебные регистры и реквизиты хранилищ значений. Отключите лишнее в свойствах и перестройте индекс.
- ❌ Слияние днём «вешает» поиск. Слияние на большой базе идёт долго и нагружает сервер. Переносите его на ночь.
- ❌ Строка поиска в списке тормозит на миллионе документов. Поиск «по любой части» во всех колонках. Сузьте видимые колонки, переключите способ на «Начало строки» или используйте ППД.
- ❌ Загрузка из файла идёт часами.
НайтиПоНаименованиюв цикле по каждой строке. Замените на один запрос и соответствие.