Skip to content
mSearch
mSearch
Полнотекстовый поиск с морфологическим анализом для MODX 3
  1. Компоненты
  2. mSearch
  3. Сниппеты
  4. mSearch

mSearch

Сниппет для поиска и вывода результатов.

Использует pdoTools для вывода, поэтому поддерживает все основные возможности: подключение TV, указание условий в &where и т.д.

Некэшируемый вызов

Сниппет должен вызываться некэшированно!), так как реагирует на поисковый запрос из $_REQUEST.

Параметры

ПараметрПо умолчаниюОписание
query$_REQUEST[queryVar]Поисковый запрос. Если не задан явно — берётся из HTTP-параметра, имя которого указано в queryVar
queryVarmse_queryИмя HTTP-параметра, из которого читается поисковый запрос. Валидируется по regex ^[a-zA-Z_][a-zA-Z0-9_]*$, при невалидном имени — fallback на mse_query
tplmSearch.rowЧанк оформления для каждого результата
tplWrapperЧанк-обёртка для всех результатов
limit10Лимит результатов. 0 — без ограничения (полезно для return=ids)
toPlaceholderСохранить результаты в плейсхолдер вместо вывода
contextsтекущий контекстКонтексты для фильтрации, через запятую (например web,ru). Пустая строка — поиск по всем контекстам
returnchunksФормат вывода: chunks, ids, json, data

Параметр return

ЗначениеОписание
chunksВывод через чанки (по умолчанию)
idsТолько ID найденных ресурсов через запятую
jsonJSON-массив с данными ресурсов
dataМассив данных (для использования в других сниппетах)

Плейсхолдеры

Глобальные плейсхолдеры

После выполнения сниппет устанавливает:

ПлейсхолдерОписание
[[+mse.total]]Общее количество найденных результатов
[[+mse.query]]Поисковый запрос

Плейсхолдеры в чанке tpl

ПлейсхолдерОписание
[[+id]]ID ресурса
[[+pagetitle]]Заголовок
[[+longtitle]]Расширенный заголовок
[[+introtext]]Вводный текст
[[+weight]]Релевантность (вес) результата
[[+intro]]Фрагмент introtext с подсвеченными совпадениями (HTML-safe)
[[+idx]]Порядковый номер в списке
и другие поля ресурса...Доступны все поля, которые загрузил pdoFetch

Поле content

По умолчанию pdoFetch не загружает поле content (тяжёлое). Чтобы получить [[+content]] в чанке, передайте &includeContent=1`` в вызов сниппета.

Плейсхолдеры в чанке tplWrapper

ПлейсхолдерОписание
[[+output]]Все результаты, склеенные подряд
[[+total]]Количество результатов
[[+query]]Поисковый запрос

Примеры

Базовый вызов

fenom
{'!mSearch' | snippet}

С кастомным чанком

fenom
{'!mSearch' | snippet : [
    'tpl' => 'mySearchResult',
    'limit' => 20
]}

С обёрткой

fenom
{'!mSearch' | snippet : [
    'tpl' => 'mSearch.row',
    'tplWrapper' => 'mSearch.wrapper',
    'limit' => 10
]}

Чанк mSearch.wrapper:

fenom
{if $total > 0}
<div class="search-results">
    <p>Найдено результатов: {$total} по запросу "{$query}"</p>
    <div class="results-list">
        {$output}
    </div>
</div>
{else}
<p>Ничего не найдено</p>
{/if}

С пагинацией через pdoPage

fenom
{'!pdoPage' | snippet : [
    'element' => 'mSearch',
    'tpl' => 'mSearch.row',
    'limit' => 10
]}

{$_modx->getPlaceholder('page.nav')}

Пагинация

Собственный параметр &offset у mSearch не предусмотрен — пагинация реализуется через обёртку pdoPage, которая управляет порциями результатов и формирует навигацию.

Получение только ID

Полезно для передачи в другие сниппеты:

fenom
{set $ids = '!mSearch' | snippet : [
    'return' => 'ids',
    'limit' => 0
]}

{if $ids}
{'msProducts' | snippet : [
    'resources' => $ids,
    'sortby' => 'ids'
]}
{else}
<p>Товары не найдены</p>
{/if}

Поиск товаров MiniShop3

fenom
{'!pdoPage' | snippet : [
    'element' => 'msProducts',
    'parents' => 0,
    'resources' => '!mSearch' | snippet : ['return' => 'ids', 'limit' => 0] | default : '999999',
    'sortby' => 'ids',
    'tpl' => 'tpl.msProducts.row'
]}

{$_modx->getPlaceholder('page.nav')}

Фильтр default

Фильтр | default : '999999' подставляет несуществующий ID, если поиск не дал результатов. Это предотвращает вывод всех товаров при пустом запросе.

JSON для AJAX

fenom
{'!mSearch' | snippet : [
    'return' => 'json',
    'limit' => 5
]}

Кастомное имя HTTP-параметра запроса

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

fenom
{'!mSearch' | snippet : ['queryVar' => 'q']}

Сниппет прочитает запрос из $_REQUEST['q'] вместо $_REQUEST['mse_query'].

Чанк по умолчанию

Чанк mSearch.row:

fenom
<div class="search-result">
    <h3>
        <a href="{$id | url}">{$pagetitle}</a>
        <span class="weight">{$weight}</span>
    </h3>
    {if $intro}
    <p class="intro">{$intro}</p>
    {/if}
</div>

Подсветка результатов

Плейсхолдер [[+intro]] — фрагмент introtext (длиной по умолчанию 200 символов вокруг первого совпадения) с подсвеченными словами в <mark>.

Highlighter экранирует исходный текст через htmlspecialchars до вставки <mark> — результат HTML-safe, можно безопасно выводить в чанке без дополнительного |escape.

Фильтрация по контексту

По умолчанию сниппет фильтрует результаты по текущему контексту MODX. Это важно для мультиконтекстных сайтов (например, мультиязычных), чтобы пользователи русского сайта не видели в результатах страницы с английского.

fenom
{* Поиск только в текущем контексте (по умолчанию) *}
{'!mSearch' | snippet}

{* Поиск в нескольких контекстах *}
{'!mSearch' | snippet : ['contexts' => 'web,ru']}

{* Поиск по всем контекстам *}
{'!mSearch' | snippet : ['contexts' => '']}

Алгоритм поиска

  1. Разбиение запроса — запрос разбивается на слова
  2. Обработка алиасов — применяются синонимы и замены
  3. Морфологический анализ — для каждого слова ищутся базовые формы
  4. Поиск в индексе — поиск слов в таблице индекса с фильтрацией по контексту
  5. LIKE-поиск — дополнительный поиск по полному тексту (mse_intro)
  6. Применение бонусов — добавление веса за точные совпадения и за вхождение всех слов
  7. Сортировка — результаты сортируются по релевантности

События

При поиске вызываются события Searcher:

  • mseOnBeforeSearch — перед поиском, можно модифицировать запрос и опции
  • mseOnAfterSearch — после поиска, можно модифицировать результаты

События вызываются в Searcher::search(), поэтому срабатывают одинаково и при использовании сниппета, и при прямом обращении к $msearch->search() (например, из своего PHP-кода).