Глобальный поиск (PRO)
Одна строка поиска по всему, что держит конструктор: блоки на страницах и строки таблиц — сразу. Открывается значком Поиск PB в верхней панели менеджера, рядом с остальными пунктами MODX.
Что бывает источником
| Источник | Когда появляется в списке |
|---|---|
| Блоки | Всегда |
| Таблица | У таблицы включена галочка Поиск, есть своя модель, таблица опубликована и не удалена |
Галочка «Поиск» у таблицы делает два дела
В конструкторе таблиц она подписана просто «Поиск», и заметнее всего то, что она рисует строку поиска над списком строк. Она же решает, попадёт ли таблица в источники глобального поиска. Сняли её, чтобы убрать поиск из грида, — таблица пропала и из глобального, хотя искомые поля у неё остались.
Таблица без своей модели — та, чьи строки лежат в общей pb_table_data, — источником не бывает: такие таблицы отсеиваются явно, до всякого поиска.
Какие поля ищутся
Поле участвует в поиске, когда у него включён флаг Искомое. Отметить его можно двумя путями, значение за ними одно (pb_fields.searchable):
- у самого поля — флаг Искомое;
- на вкладке Поиск в конструкторе таблицы — списком, не открывая каждое поле.
Столбцы грида тут ни при чём: поле может быть искомым, не показываясь в списке, и наоборот.
Колонка или ключ в data — ищется и то и другое
Искомое поле может быть настоящей колонкой таблицы, а может лежать ключом в JSON-колонке data — см. Модели. Поиск сам разбирает, что есть что, и собирает для каждого свой запрос:
LOWER(`field_name`) LIKE '%запрос%' -- колонка
LOWER(JSON_UNQUOTE(JSON_EXTRACT(`data`, '$."field_name"'))) LIKE ? -- ключ в dataПравило то же, что у поиска внутри грида таблицы: есть колонка — идём по ней, нет — ищем ключ с таким именем в data.
Раньше такое поле выключало поиск по всей таблице
До этого поиск умел только колонки. Одно поле из data роняло запрос на неизвестной колонке, ошибка гасилась — и таблица молча возвращала пустой результат, без сообщения в интерфейсе. Со стороны это читалось как «поиск ничего не находит», а не как «поле отмечено неправильно». Если вы снимали флаг Искомое с таких полей, чтобы обойти это, — верните.
Поле, которому не соответствует ни колонка, ни колонка data у таблицы, просто пропускается: остальные поля ищутся как ни в чём не бывало.
Числовой запрос ищет ещё и по номеру
Запрос целиком из цифр дополнительно сверяется с id строки. 1234 найдёт и строку с таким номером, и строку, где 1234 встретилось в тексте искомого поля.
Побочное следствие: таблица без единого искомого поля на числовой запрос всё равно ответит — по номеру строки.
Поиск по блокам
Блоки ищутся по трём колонкам pb_block_data сразу: имя блока, чанк и data целиком. Удалённые блоки пропускаются, новые идут первыми.
По JSON находится больше ожидаемого
data сверяется как обычный текст, вместе с именами ключей. Запрос title найдёт блок не только по значению поля, но и по его имени.
Минимум два символа
Запрос короче двух символов возвращает пустой результат, не обращаясь к базе.
Это не сообщение о неправильном вводе
Ответ будет success без строк, а не ошибка: строка поиска срабатывает по мере набора, с задержкой в 350 мс. Одна буква по всем блокам большого сайта — это перебор всей таблицы, который никому не поможет.
Сколько находится за раз
Из каждого источника берётся 50 строк. Пагинации нет намеренно: поиск сужают выбором источника, а не листанием выдачи.
Источников можно выбрать несколько — они опрашиваются по очереди, и в статусе видно, какой сканируется сейчас. Без выбора ищется везде: блоки плюс все таблицы, то есть до 50 + 50 × число таблиц строк.
Как выглядит результат
| Блок | Строка таблицы | |
|---|---|---|
| Заголовок | Имя блока | «Имя таблицы #id» |
| Подзаголовок | Чанк | — |
| Описание | Фрагмент текста вокруг совпадения, 140 символов | Значения искомых полей через · |
Клик открывает объект на месте: блок — окном правки блока, строку — окном строки таблицы. У строк своей модели в результате приходит ещё и адрес на сайте, если он выводится.
Это LIKE, а не полнотекстовый индекс
FULLTEXT-индексов компонент не заводит и не использует. LIKE '%…%' не опирается на обычный индекс даже там, где он есть, а поиск по data — это полный перебор pb_block_data.
На небольшом сайте это незаметно. На сайте с сотнями тысяч блоков или строк — заметно, и лечится выбором источника: одна таблица вместо «везде».
Неопубликованное находится, удалённое — нет
Это поиск редактора: он ищет контент, чтобы его править, и потому не фильтрует выдачу по публикации. Неопубликованная строка и неопубликованный блок находятся наравне с остальными — иначе поиском нельзя было бы дописать черновик.
Удалённое не находится: строки и блоки, лежащие в корзине, отсеиваются по deleted_at. У таблицы, где такой колонки нет вовсе, отсеивать нечего — проверка это учитывает и запрос не ломает.
Поиска по сайту здесь нет
Обе точки поиска закрыты авторизацией менеджера и платной сборкой, так что позвать их с фронта нельзя. Поиск для посетителей — отдельная вещь: свой контроллер, свой запрос, свой шаблон. Требования у них разные, и общий поиск означал бы либо показать посетителю неопубликованное и удалённое, либо спрятать это от редактора.