javascript

Poisk: однофайловый поисковик для изолированной корпоративной сети

  • четверг, 29 января 2026 г. в 00:00:10
https://habr.com/ru/articles/989692/

Проблема и контекст

В изолированной корпоративной сети с сотнями тысяч файлов стандартные инструменты поиска неэффективны. Сотрудники тратят часы на ручной перебор каталогов, чтобы найти нужный документ по пути или названию. Облачные решения неприменимы из-за требований безопасности, а серверные поисковые системы требуют инфраструктуры и администрирования.

Типичные условия:

  • Сотни тысяч файлов в десятках каталогов на сетевом хранилище

  • Смешанный парк компьютеров: Windows и Linux-дистрибутивы

  • Нет доступа в интернет, строгие политики безопасности

  • Отсутствие выделенных ресурсов для администрирования

Суть решения: отказ от серверной архитектуры в пользу одного HTML-файла, содержащего данные, логику и интерфейс.


Архитектурное ядро

Почему один HTML-файл?

сборка поискового файла
сборка поискового файла

Выбор однофайловой модели решает три практические проблемы изолированных сетей:

  1. Безопасность: антивирусное ПО редко блокирует HTML-файлы, в отличие от исполняемых скриптов

  2. Портативность: нет зависимостей, работает в любом современном браузере

  3. Простота распространения: один файл можно скопировать в любую точку сети

Двухэтапная модель работы

два этапа работы системы
два этапа работы системы

Система разделена на два независимых этапа:

Этап А: Фоновая индексация (Python)

Для каждого каталога в конфигурации:
    Присвоить уникальный номер
    Запомнить короткое имя и путь до каталога
    Рекурсивно обойти все файлы внутри каталога
    Отфильтровать по расширениям (pdf, docx, xlsx...)
    Для каждого подходящего файла:
        Вычислить путь относительно корня каталога
        Сохранить: [номер_каталога, путь_внутри_каталога]
    Упаковать массив + HTML-шаблон + CSS + JS → search.html

Этап Б: Клиентский поиск (JavaScript в браузере)

При загрузке страницы:
    Загрузить массив каталогов и массив файлов в память

При вводе запроса:
    Привести запрос к нижнему регистру, разбить на слова
    Для каждого файла в массиве:
        Получить путь внутри каталога
        Если все слова содержатся в пути → добавить в результаты
    Для каждого результата:
        По номеру каталога получить его путь от search.html
        Объединить: путь_каталога + путь_файла
    Отсортировать и отобразить результаты

Ключевые решения

1. Структура индекса с разделением путей

Индекс строится в два уровня для экономии места:

  1. Массив каталогов: содержит номер, короткое имя и путь от search.html

  2. Массив файлов: содержит номер каталога и путь к файлу внутри него

Пример фактической структуры в HTML:

<script>
// Минималистичное хранение без имён полей
const catalogs = [
  [1, "Договоры", "Общие/Документы/Договоры"],
  [2, "Отчеты", "Финансы/Отчетности"]
];

const files = [
  [1, "2024/Январь/договор_123.pdf"],
  [2, "Квартальные/отчет_Q1.xlsx"]
];
</script>

Преимущества:

  • Сокращение размера данных (имена каталогов не дублируются)

  • Быстрая обработка при поиске

  • Простота обновления при изменении структуры

2. Алгоритм поиска с реконструкцией полного пути

функция поиск(запрос, каталоги, файлы):
    слова = очистить_и_разбить_запрос(запрос)
    результаты = []
    
    для каждого файла в файлах:
        если все_слова_в_пути(слова, файл.путь):
            каталог = найти_каталог_по_id(каталоги, файл.id_каталога)
            полный_путь = объединить_пути(каталог.путь, файл.путь)
            добавить_в_результаты(результаты, каталог, полный_путь, файл)
    
    отсортировать(результаты)
    вернуть результаты

При отображении результатов JavaScript объединяет путь каталога (от search.html) с путем файла (внутри каталога), формируя полный относительный путь, который используется для навигации.


Развёртывание и администрирование

ярлыки запуска сборки поисковых файлов для абминистратора
ярлыки запуска сборки поисковых файлов для абминистратора

Настройка и поддержка системы выполняется администратором и сводится к минимальным действиям. В специальном каталоге находятся ярлыки для запуска процесса индексации и файл конфигурации config.ini, где задаются пути сканирования и параметры. Для обновления поискового файла администратор запускает скрипт generate_search_page.py, который выполняет полное сканирование указанных сетевых каталогов.

начало лога сборки со списком папок сканирования
начало лога сборки со списком папок сканирования

Процесс индексации выполняется в терминале с визуализацией прогресса: отображается текущий обрабатываемый каталог, количество найденных файлов и общее время выполнения. Для объёма в несколько сотен тысяч файлов процесс занимает до часа, но выполняется в фоновом режиме, обычно ночью по расписанию. По завершении в указанной сетевой папке появляется обновлённый файл search.html, готовый к использованию всеми сотрудниками. Таким образом, администрирование системы требует минимального вмешательства — только периодический запуск индексации и при необходимости корректировка конфигурации.

окончание лога сборки
окончание лога сборки

Интерфейс

верхняя часть интерфейса с каталогами сканирования, поисковой строкой и выдачей
верхняя часть интерфейса с каталогами сканирования, поисковой строкой и выдачей
нижняя часть интерфейса с остатком выдачи и информацией о базе поиска
нижняя часть интерфейса с остатком выдачи и информацией о базе поиска

Интерфейс сознательно минималистичен:

  • Строка поиска с мгновенными результатами

  • Счётчик найденных файлов

  • Список результатов с подсветкой совпадений

Рабочий процесс:

  1. Пользователь открывает search.html с сетевого диска

  2. Вводит слова из названия или пути искомого файла

  3. Видит результаты в реальном времени с подсветкой совпадений

Навигация по результатам:

  • Клик по отображаемому пути → открытие папки в новом окне браузера

  • Клик по имени файла → открытие (PDF) или скачивание (DOCX, XLSX)

открытие папки в новом окне браузера
открытие папки в новом окне браузера
открытие (PDF)
открытие (PDF)

Интерфейс выступает мостом между поисковым запросом и файловой системой, позволяя перейти от поиска к работе с файлом за два клика.


Результаты и ограничения

Фактические результаты работы системы:

  • Обработано: 566 288 файлов в 47 каталогах

  • Размер итогового файла: 120 МБ

  • Время загрузки в браузере: 2-3 секунды

  • Время поиска: менее 1 секунды

Осознанные ограничения решения:

  1. Только поиск по путям и именам файлов
    Содержимое документов не индексируется.

  2. Работа в рамках одного сетевого ресурса
    Все каталоги сканирования должны быть доступны из места размещения search.html.

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

Область эффективного применения:

  • Изолированные корпоративные сети

  • Стабильные файловые структуры, где важная информация содержится в путях

  • Ситуации, когда нет возможности развернуть серверное ПО

  • Смешанный парк операционных систем

Область неэффективного применения:

  • Системы, где требуется поиск по содержимому документов

  • Динамически изменяющиеся файловые хранилища

  • Сценарии, требующие поиска в реальном времени


Что сделано

Poisk — это рабочее решение конкретной проблемы: навигации по сотням тысяч файлов в изолированной корпоративной сети. Система доказала свою жизнеспособность на реальных данных.

Основные достижения:

  1. Создан полностью автономный инструмент — один HTML-файл содержит всё необходимое для работы

  2. Достигнута высокая производительность — поиск по сотням тысяч записей выполняется за доли секунды

  3. Обеспечена кроссплатформенность — работает на Windows и Linux без дополнительных настроек

  4. Решена проблема разнородности путей — механизм относительных путей работает независимо от способа монтирования сетевых дисков

  5. Минимизированы требования к инфраструктуре — не нужны серверы, базы данных или специальное ПО

Система не претендует на замену полноценных корпоративных поисковых решений, но эффективно закрывает нишу быстрой навигации по файловой структуре в условиях, когда развёртывание серверных систем невозможно или нецелесообразно.

Архитектура Poisk демонстрирует, что для чётко очерченной задачи можно создать простое и эффективное решение, используя возможности современных браузеров как платформы выполнения.

Исходный код и дистрибутив: https://github.com/prog815/poisk