WordPress и внешний поиск: типичные ошибки интеграции
Внешний поиск в WordPress ломается не только из-за API. Черновики попадают в индекс, удалённые записи остаются в выдаче, а WP-Cron теряет события. Разбираем границы интеграции и способы сделать синхронизацию предсказуемой.

Внешний поиск для WordPress часто выглядит простым: отправить записи в поисковый сервис и показывать результаты вместо стандартной выдачи. На практике рассинхронизация начинается уже после первого редактирования: автосохранение создаёт лишнее событие, удалённая статья продолжает находиться, а WP-Cron не запускает очередь вовремя. Ниже — рабочие приёмы для WordPress 6.x: как выбрать схему синхронизации, какие данные отправлять и где искать причину устаревшей выдачи.
Сначала определите границу интеграции
Внешний поиск состоит из двух разных частей. WordPress хранит контент и решает, какие записи доступны пользователю. Поисковый сервис строит собственный индекс и отвечает за релевантность, фильтры и подсказки.
Ошибка начинается, когда эти обязанности смешивают. Поисковый сервис не должен самостоятельно решать, можно ли показывать черновик, закрытую запись или материал, доступный только авторизованным пользователям. WordPress должен передавать в индекс только публичные данные, а поиск — возвращать идентификаторы и поля, по которым сайт строит карточку результата.
Индекс — это не копия базы WordPress, а производная витрина. Источником истины остаётся WordPress, а поисковый сервис можно пересоздать.
Индекс1 — отдельное представление данных, подготовленное для быстрого поиска. Он может содержать заголовок, текст, таксономии и URL, но не обязан повторять структуру таблиц WordPress.
Три схемы синхронизации и их цена
У WordPress-интеграций обычно три подхода. Выбор зависит от объёма контента, допустимой задержки и того, можете ли вы запустить отдельного обработчика очереди.
| Схема | Плюс | Цена и риск | Когда выбирать |
|---|---|---|---|
| Синхронно при сохранении | Изменения почти сразу попадают в индекс | Сохранение записи зависит от внешнего API; тайм-аут может мешать редактору | Небольшой сайт, низкая цена задержки, стабильный сервис поиска |
| Очередь и фоновый обработчик | Редактор WordPress не ждёт внешний сервис; события можно повторять | Нужны очередь, идемпотентность и мониторинг | Рабочий сайт с регулярными публикациями и массовыми изменениями |
| Периодический полный экспорт | Простая логика, легко пересоздать индекс | Между экспортами выдача устаревает; полный проход нагружает WordPress | Каталог с редкими изменениями или резервный сценарий |
На практике устойчивее всего сочетать очередь для изменений с полным экспортом по расписанию. Очередь сокращает задержку, а полный экспорт исправляет пропущенные события и позволяет проверить целостность индекса.
Ошибки, из-за которых поиск показывает не то
Автосохранения и ревизии принимают за публикацию
WordPress сохраняет записи не только после нажатия кнопки публикации. Редактор может создавать автосохранения, а плагины — обновлять запись несколько раз за один цикл. Если отправлять каждое событие во внешний поиск, вы получите лишние запросы, дубли в очереди и гонки: более старое содержимое иногда доезжает позже нового.
Обрабатывайте изменение только после проверки статуса записи и её типа. Для публичного материала проверяйте, что статус — publish, а тип записи действительно должен участвовать в поиске. В очередь передавайте идентификатор записи и версию изменения или время обновления. Сам текст можно перечитать из WordPress перед индексацией, чтобы не отправлять устаревший payload.
Проверка: создайте черновик, измените его несколько раз, затем опубликуйте. В журнале должна появиться одна актуальная операция индексации, а не отдельная запись на каждое автосохранение.
Удаление обрабатывается как обычное обновление
При удалении записи внешнему сервису обычно нужно отправить отдельную операцию удаления. Если интеграция реагирует только на сохранение, карточка исчезает из WordPress, но остаётся в поисковой выдаче и ведёт на 404.
Удаление нужно ставить в очередь отдельно. Для этого передавайте постоянный идентификатор записи, а не только URL: адрес мог измениться после редактирования постоянной ссылки. После удаления проверяйте не только обычный поиск, но и фильтры по рубрике и тегу.
В индекс попадают закрытые материалы
Проверки на стороне шаблона недостаточно. Сайт может скрыть ссылку на черновик, но поисковый сервис уже успеет проиндексировать его заголовок и фрагмент текста. Это особенно опасно для закрытых записей и материалов с персональными данными.
- Фильтруйте записи по статусу до отправки во внешний сервис.
- Отдельно проверяйте тип записи, рубрики, языки и признаки приватности.
- Не передавайте в индекс метаполя, которые не нужны для выдачи.
- Для закрытого контента не полагайтесь на скрытый URL: используйте авторизацию и проверку доступа.
Проверка: создайте тестовую запись с пометкой «только для редактора» и убедитесь, что её заголовок не находится через внешний поиск в режиме гостя.
WP-Cron принимают за настоящую очередь
WP-Cron запускается при посещении сайта, а не как постоянно работающий планировщик. Если на сайте мало трафика, очередь может ждать часами. Если трафика много, несколько процессов могут одновременно запустить одну и ту же задачу.
Для критичной синхронизации используйте внешний планировщик или постоянный обработчик очереди, если это поддерживает ваша инфраструктура. В самой задаче храните статус операции: pending, processing, done или failed. Повторная попытка должна быть безопасной: повторная отправка одной записи не должна создавать второй документ.
Не удаляйте ошибочные задания после первой неудачи. Сохраняйте код ответа, время следующей попытки и текст ошибки без секретов. Ограничьте число повторов, иначе недоступный поисковый сервис создаст бесконечную нагрузку на сайт.
Пагинация теряет записи
При первом импорте нельзя рассчитывать, что один запрос вернёт весь контент. REST API WordPress ограничивает размер страницы, а поисковые сервисы тоже могут принимать документы пакетами. Типичный дефект — экспорт первых 100 записей без проверки общего количества страниц.
Читайте заголовки ответа REST API и продолжайте экспорт до последней страницы. В WordPress REST API для коллекций используются заголовки X-WP-Total и X-WP-TotalPages; точные ограничения на размер страницы зависят от endpoint и версии. Для больших объёмов ставьте паузу между пакетами и отслеживайте HTTP-коды ответа.
curl -sS -D headers.txt \
'https://example.com/wp-json/wp/v2/posts?status=publish&per_page=50&page=1' \
-o page-1.json
Команда подходит для проверки REST API WordPress 6.x. Она сохраняет заголовки в отдельный файл: по ним можно увидеть число страниц и понять, не оборвался ли экспорт на первой порции. Домен и путь замените на свой сайт; авторизацию и секреты не помещайте в команду, которая попадёт в историю shell.
Отправляйте в индекс нормализованные данные
Поиску редко нужен исходный HTML записи целиком. Перед отправкой сформируйте отдельный документ с устойчивой схемой:
id— числовой идентификатор записи WordPress;typeиstatus— тип и публичный статус;title— заголовок без лишней разметки;contentилиexcerpt— текст для полнотекстового поиска;url— текущий канонический адрес;terms— рубрики, теги или другие фильтры;updated_at— время последнего изменения.
Не смешивайте в одном поле HTML, короткие коды и видимый текст. Пользователь ищет слова, которые видит на странице, а не служебную разметку. Если контент собирается из блоков Gutenberg, проверьте результат на реальных записях: таблицы, подписи к изображениям и встроенные блоки могут превращаться в неудобный для поиска текст.
Где подход ломается
Даже корректная очередь не решает все случаи. Перед запуском проверьте граничные сценарии:
- Изменился URL. Индекс может содержать старый и новый адрес. Обновляйте документ по идентификатору и отдельно решите, нужны ли редиректы.
- Сработали два обновления подряд. Более старая задача не должна перезаписать новую. Сравнивайте версию или время изменения перед применением.
- Внешний сервис вернул 429. Это ограничение частоты запросов, а не повод повторять запросы без паузы. Используйте задержку и ограниченное число повторов.
- Один сайт обслуживает несколько языков. Язык должен входить в документ и фильтр. Иначе русская и английская версии смешаются в одной выдаче.
- Индекс пересоздали вручную. После очистки внешнего сервиса нужно запустить полный экспорт, а не ждать новых событий: старые записи уже не вызовут событие изменения.
Смежная тема — настройка релевантности и морфологии конкретного поискового движка; здесь важнее целостность данных между WordPress и индексом.
Что измерять после запуска
Не ограничивайтесь проверкой одного поискового запроса. Минимальный набор метрик состоит из числа задач в очереди, возраста самой старой необработанной задачи, доли ошибок и задержки от публикации до появления результата. Отдельно считайте количество документов в WordPress и во внешнем индексе по типам записей.
Раз в неделю запускайте сверку: выгрузите список публичных идентификаторов WordPress и сравните его со списком документов индекса. Это быстрее обнаружит пропущенное удаление или оборвавшийся импорт, чем жалоба пользователя на старую карточку.
Что делать дальше
Начните с тестового индекса и пяти сценариев: публикация, редактирование, удаление, смена URL и повторная отправка одной задачи. Затем добавьте очередь с ограниченными повторами и отдельную полную пересборку. В проде первым показателем поставьте возраст самой старой задачи: если он растёт, проблема уже не в релевантности, а в доставке изменений.
Поиск источников: Реальные статьи и книги со ссылками, библиография по ГОСТ
Спросить за 15 ₽Источники: WordPress REST API Handbook, WordPress Plugin Handbook: Hooks
Частые вопросы
Можно ли подключить внешний поиск без отдельной очереди?
Почему удалённая запись всё ещё находится в поиске?
Что будет, если WP-Cron не запустит задачу вовремя?
Нужно ли индексировать весь HTML записи?
Как понять, что потерялись записи при импорте?
Что делать, если поисковый сервис вернул ошибку 429?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.