Поиск в WordPress: как работает и как сделать поиск по метаполям

Поиск в WordPress: как работает и как сделать поиск по метаполям

Кратко: стандартный поиск WordPress ищет только по заголовку, тексту и цитате записи — метаполя (ACF, произвольные поля) он не видит. Чтобы искать по метаполям, нужно вмешаться в запрос через pre_get_posts и добавить meta_query с связью OR, либо сделать отдельный поисковый запрос через WP_Query. Для больших каталогов такой поиск быстро упирается в производительность: помогают индексы, кеширование и полнотекстовый поиск. Ниже — как устроен поиск, рабочие примеры кода, ловушки и чек-лист.

Как работает стандартный поиск WordPress

Когда посетитель вводит запрос, WordPress создаёт обычный запрос к базе с параметром s. Ищется совпадение по трём колонкам таблицы записей: post_title, post_content и post_excerpt. Учитываются только опубликованные записи — плюс фильтры по статусу и типу, если они заданы.

Отсюда две особенности. Первая: поиск не учитывает ничего, что хранится вне этих трёх полей, — цены, артикулы, города, характеристики товаров. Вторая: совпадения ищутся по подстроке, поэтому «окно» найдётся и в слове «подоконник», а релевантность выдачи невысокая. Regex и полнотекстовые индексы ядро не использует.

На практике это значит: для блога штатного поиска достаточно, для каталога с характеристиками — нет. И это одна из самых частых жалоб «поиск не находит товар, хотя он есть».

Почему метаполя не находятся

Метаполя хранятся в отдельной таблице postmeta и к запросу поиска не подключаются. Даже если в описании товара есть «двухкамерный», а в настройке — «цена 12 000», поиск по «двухкамерный» ничего не вернёт, пока вы не добавите условие по метаданным.

Есть три уровня решения. Первый — добавить meta_query к поисковому запросу. Второй — искать в отдельном запросе через WP_Query с нужными параметрами. Третий — вынести данные в отдельную таблицу с полнотекстовым индексом, если каталог большой. Для большинства сайтов достаточно первых двух.

Подход Что даёт Когда подходит
Хук pre_get_posts + meta_query Штатный поиск начинает видеть метаполя Небольшой и средний каталог
Отдельный WP_Query Полный контроль над условиями и сортировкой Кастомная страница поиска
FULLTEXT / внешний поиск Быстрый поиск по большим объёмам Тысячи записей и сложная релевантность

Поиск по метаполям через pre_get_posts

Самый аккуратный способ — добавить метаусловие к основному поисковому запросу, не ломая остальные страницы. Хук срабатывает до выполнения запроса, поэтому мы можем изменить его параметры.

add_action( 'pre_get_posts', function ( $query ) {
    if ( is_admin() || ! $query->is_main_query() || ! $query->is_search() ) {
        return;
    }
    $meta_query = array(
        'relation' => 'OR',
        array(
            'key'     => 'price',
            'value'   => $query->get( 's' ),
            'compare' => 'LIKE',
        ),
        array(
            'key'     => 'article',
            'value'   => $query->get( 's' ),
            'compare' => 'LIKE',
        ),
    );
    $query->set( 'meta_query', $meta_query );
}, 10 );

Важно: relation => OR означает «подходит любое из условий». С параметром compare => 'LIKE' поиск будет искать подстроку — так «артикул 123» найдётся по частичному совпадению. Не забывайте проверять is_admin() и is_main_query(): без этого хук сломает админку и все остальные страницы.

Такой код удобно хранить в дочерней теме, а не в родительской: обновление темы не снесёт правку. Как это организовать — в статье дочерняя тема WordPress: как создать и зачем нужна. Если тема не ваша, код ставится в свой маленький плагин.

Отдельный поисковый запрос

Если нужно искать только по определённому типу записей и с собственной сортировкой, штатный поиск лучше не трогать, а построить свой WP_Query. Это даёт полный контроль: какие поля искать, в каком порядке выводить, сколько результатов показывать.

$search = get_search_query();
$args = array(
    'post_type'      => 'product',
    'posts_per_page' => 20,
    'meta_query'     => array(
        'relation' => 'OR',
        array( 'key' => 'sku', 'value' => $search, 'compare' => 'LIKE' ),
        array( 'key' => 'brand', 'value' => $search, 'compare' => 'LIKE' ),
    ),
);
$results = new WP_Query( $args );

Логику запросов к базе и тонкости WP_Query удобно освежить по материалам $wpdb в WordPress: безопасные запросы и хуки WordPress: actions и filters. Если пишете свой запрос руками через $wpdb, обязательно используйте подготовленные выражения — иначе получите SQL-инъекцию.

Своя форма и страница результатов

Стандартная форма поиска выводит только поле и кнопку. Если нужно искать по каталогу, добавьте подсказки: выбор категории, чекбоксы характеристик, подсказки при вводе. Это снижает число пустых запросов и помогает найти товар с первого раза.

Шаблон вывода результатов (search.php) стоит доработать: показывать, что именно найдено, подсвечивать совпадение, выводить «ничего не найдено» с подсказками и популярными разделами. Пустая страница без объяснений — частая причина ухода посетителя.

Не забудьте про пагинацию результатов: постраничная навигация должна работать и на странице поиска, иначе глубокая выдача недоступна. Как её вывести — в статье Пагинация в WordPress.

Релевантность и сортировка

Простой LIKE-поиск не умеет ранжировать: он находит совпадения, но не говорит, какое из них важнее. Для небольшого каталога хватает эвристики: точное совпадение по артикулу — выше, совпадение в заголовке — выше, чем в описании. Реализуется через несколько запросов или сортировку результатов на PHP.

Что ищем Где хранить Как искать
Артикул, SKU Метаполе LIKE, точное совпадение в приоритете
Цена, характеристики Метаполе meta_query с числовым compare
Название и описание post_title / post_content Штатный поиск
Большой текст Отдельная таблица / FULLTEXT MATCH AGAINST с индексом

Для тысяч записей LIKE-запросы становятся узким местом: они не используют индексы по подстроке. Тогда либо ограничивают область поиска, либо переходят на полнотекстовый индекс, либо подключают внешний поисковый сервис.

Поиск по метаполям в админке

Редактору тоже нужен поиск: в списке записей и товаров стандартное поле ищет только по заголовку. Чтобы искать по метаполям в админке, добавляют фильтр posts_search или отдельное поле фильтра через restrict_manage_posts и parse_query.

Осторожно с производительностью: админский поиск по метаполям на большом каталоге может грузить базу. Если записей много, лучше сделать отдельный отчёт или выгрузку, чем искать по всем метаданным каждый раз.

Скорость и типичные ошибки

Поиск по метаполям — это JOIN к таблице postmeta на каждый запрос. Чем больше условий, тем тяжелее запрос. Помогают индексы по meta_key и кеширование результатов частых запросов.

Ошибка Последствие Как правильно
Хук без проверки is_admin() Ломается админка и другие страницы Проверять is_main_query и is_search
LIKE по всем метаполям Тяжёлые запросы, медленный поиск Ограничить набор полей
Нет проверки пустого запроса Поиск возвращает всё подряд Проверять длину запроса
Ручной SQL без подготовки SQL-инъекция Использовать prepared statements
Нет кеша частых запросов База под нагрузкой Кеш результатов на 10–30 минут

Кеширование результатов поиска — отдельная тема: частые запросы («окна», «ремонт») повторяются десятки раз в день, и их выгодно кешировать на короткое время. Как это устроено, разобрано в статье транзиенты в WordPress.

Чек-лист внедрения

1. Определите, по каким полям действительно ищут: артикул, бренд, город, характеристики. 2. Добавьте meta_query через pre_get_posts с проверками is_admin и is_main_query. 3. Ограничьте набор полей и длину запроса. 4. Проверьте сортировку: точные совпадения выше частичных. 5. Сделайте понятную страницу «ничего не найдено». 6. Проверьте пагинацию и работу на мобильном. 7. Замерьте время ответа до и после. 8. Настройте кеш частых запросов. 9. Проверьте поиск при пустом запросе и при спецсимволах. 10. Прогоните тесты на копии сайта перед публикацией.

TimeWeb

Частые вопросы про поиск по метаполям WordPress

Почему WordPress не находит товар по характеристике?

Потому что стандартный поиск смотрит только в заголовок, текст и цитату записи, а характеристики хранятся в метаполях (postmeta). Нужно добавить условие meta_query к поисковому запросу через pre_get_posts или строить отдельный WP_Query — тогда метаполя начнут участвовать в поиске.

Не сломает ли pre_get_posts остальные страницы?

Сломает, если не ограничить хук. Всегда проверяйте is_admin(), is_main_query() и is_search(): тогда изменения затронут только главный поисковый запрос на фронтенде, а админка, архивы и страницы останутся прежними.

Почему поиск по метаполям медленный?

Каждое метаусловие добавляет JOIN к таблице postmeta, а LIKE-поиск по подстроке не использует индексы. Ускоряют: ограничение числа полей, кеширование частых запросов, индексы по meta_key, а для больших каталогов — полнотекстовый индекс или внешний поисковый движок.

Можно ли искать сразу по нескольким полям?

Да, через meta_query с relation => ‘OR’ — совпадение хотя бы в одном поле. Для более сложных условий комбинируют группы: внутри группы AND, между группами OR. Слишком много условий замедляет запрос, поэтому набор полей стоит ограничить разумным минимумом.

Как сделать поиск по метаполям в админке?

Через фильтры posts_search или связку restrict_manage_posts и parse_query: добавить поле фильтра в список записей и подмешать условие в запрос. На больших каталогах такой поиск может нагружать базу, поэтому его ограничивают или заменяют отчётом.

Нужен ли отдельный поисковый плагин?

Для небольшого и среднего каталога хватает несколько строк кода в собственной дочерней теме или плагине — это прозрачнее и легче. Плагины и внешние сервисы (например, Elasticsearch) оправданы, когда записей тысячи, нужна сложная релевантность и морфология, а LIKE-поиск уже не справляется.

Вывод

Стандартный поиск WordPress работает только по трём полям и не видит метаданные. Чтобы искать по характеристикам, артикулам и ценам, добавьте meta_query через pre_get_posts или постройте отдельный запрос. Для небольшого каталога этого достаточно, для большого — продумайте индексы, кеш и полнотекстовый поиск.

Если нужна доработка поиска по каталогу, настройка фильтров или ускорение выборок — эту задачу можно передать одной команде. Мы разбираем структуру данных, настраиваем поиск и кеш, проверяем производительность на реальных объёмах. Посмотрите услуги разработки и поддержки сайтов, изучите портфолио проектов и почитайте блог о WordPress. Опишите задачу через форму контактов — предложим решение и рассчитаем стоимость.

Clearfy

Поделиться:
Telegram ВКонтакте