besnovatyj / yii2-cms-search-tnt
Ядро сквозного поиска на TNTSearch для Yii2 CMS: полнотекстовый индекс BM25 со стеммингом русского и поиском с опечатками, размещённый в базе проекта. Подключается к фасаду besnovatyj/yii2-cms-search, отдельного демона не требует.
Package info
github.com/besnovatyj/yii2-cms-search-tnt
Type:yii2-extension
pkg:composer/besnovatyj/yii2-cms-search-tnt
Requires
- php: >=8.4
- ext-mbstring: *
- ext-pdo: *
- besnovatyj/yii2-cms-contracts: ^1.0
- besnovatyj/yii2-cms-kernel: ^1.0
- besnovatyj/yii2-cms-search: ^1.0
- teamtnt/tntsearch: ^5.3
- yiisoft/yii2: ~2.0.0
Requires (Dev)
- roave/security-advisories: dev-latest
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-09-07 13:44:10 UTC
README
Ядро для фасада besnovatyj/yii2-cms-search. Полнотекстовый индекс
живёт в той же MySQL, что и контент: на сервере ставить нечего — ни демона, ни порта, ни роли
ansible.
Оформлено модулем, а не пакетом: ядро включают и выключают менеджером модулей, стеммер и окно совпадений настраивают в админке (раздел настроек «Search»), а служебные таблицы заводятся миграциями при установке. Выключенный модуль означает «этого ядра в системе нет» — фасад перестанет предлагать его в настройках и останется на своём.
Что умеет
| Возможность | Есть | Как сделано |
|---|---|---|
| Ранжирование BM25 | да | штатно в TNTSearch |
| Стемминг русского | да | Snowball (RussianStemmer); по умолчанию выбирается по языку сайта, можно задать явно в настройках |
| Лемматизация | нет | «люди» → «человек» не найдёт; за этим — ядро Manticore |
| Поиск с опечатками | да | многобайтный Левенштейн библиотеки (кириллица считается по символам) |
| Подсветка совпадений | да | текст экранируется до подсветки, наружу идут только <mark> |
| Вкладки по разделам | да | собственная карта «документ → раздел» |
| Веса разделов | приблизительно | полевых весов у движка нет: заголовок и ключевые слова повторяются в индексируемой строке, и BM25 поднимает их через частоту |
| Подсказка «возможно, вы имели в виду» | нет | |
| Сортировка по дате | нет | движок хранит только текст |
Граница применимости
TNTSearch не хранит атрибутов и не фильтрует выдачу. Ядро забирает у него совпадения одним списком (по умолчанию до 2000 на запрос — настройка «Окно совпадений»), после чего фильтрует по разделам и режет на страницы само. Для сайта в тысячи документов это незаметно; когда типичный запрос начнёт упираться в потолок, пора переходить на ядро Manticore — контракт фасада, провайдеры модулей и вёрстка выдачи при этом не меняются.
Ориентир заявлен ядром в паспорте возможностей (comfortableSize) и виден на странице состояния
индекса в админке.
Настройки (админка, раздел «Search»)
| Опция | Смысл |
|---|---|
| Стеммер | по языку сайта, русский, английский или без стеммера. После смены нужна полная пересборка: отсечённые основы лежат в индексе, и собранный другим стеммером индекс молча перестаёт отвечать |
| Окно совпадений | сколько совпадений ядро забирает за запрос: от него зависят глубина листания и точность цифр на вкладках |
Служебные таблицы
Заводятся миграциями модуля при установке; содержимое полностью восстановимо переиндексацией — таблицы можно исключать из дампа базы:
search_tnt_map— карта «документ → раздел» по слотам;search_tnt_state— какой слот сейчас рабочий.
Кроме них есть таблицы самого индекса — bescms_search_a_* и bescms_search_b_* (по пять на
слот). Их создаёт и удаляет библиотека TNTSearch в момент пересборки, поэтому миграциями они не
описываются: их жизненный цикл привязан к индексу, а не к установке модуля.
Два слота нужны для атомарной подмены: индекс собирается в свободный слот, и рабочим он становится одним обновлением строки состояния. Поэтому пересборка не оставляет сайт без поиска, а прерванная сборка не портит рабочий индекс.
Требования
- установленный и включённый модуль фасада
Search; - MySQL-подключение (
Yii::$app->db) — реквизиты берутся из него же, отдельных секретов не заводится; - DSN с
host(TNTSearch подключается по TCP и не умеет unix-сокет); ext-pdo,ext-mbstring.
Как ядро подключается к фасаду
Module реализует Besnovatyj\Search\contracts\SearchEngineProvider и объявляет один
дескриптор: ключ tnt, подпись для настроек и класс движка. Больше фасаду ничего не нужно — он
находит ядро обходом модулей и создаёт движок контейнером. Вся DI-проводка пакета живёт в
src/config/common.php (секция container.singletons): ни config/container.php, ни
Bootstrap-класса здесь нет, потому что к модулю ядра никто не обращается напрямую.