Вопрос или проблема
Я пытаюсь сделать стандартный поиск WP немного более интеллектуальным, используя пользовательские поля. Он ищет мои пользовательские типы записей, но только по обычным полям (выдержка, заголовок, контент).
В своих аргументах к WP_Query я указываю все типы записей. Но не уверен, как точно указать все пользовательские поля с OR
, потому что я по сути ищу контент в каждом типе записи.
Код ниже не работает, дает 0 результатов для ключевого слова качественный
, например. Но прямой поиск в MySQL по таблице wp_postmeta
показывает, что есть 12 записей со словом “качественный” в них. Я хочу, чтобы мой запрос вывел все эти записи.
Как правильным образом включить их в WP_Query?
- Без фильтров / действий
- Без плагинов. Я хотел бы сделать это непосредственно в WP_Query и это должно поддерживать два языка. Мне нужно будет запрашивать только один язык в каждом поисковом движке (PolyLang).
Код:
$SEARCH = $_GET['s'];
$args = array(
's' => $SEARCH
,'orderby' => 'relevance'
,'post_type' => array('page', 'services', 'resources', 'events', 'reports', 'posts')
,'post_status' => 'publish'
,'posts_per_page' => 15
,'meta_query' => array(
'relation' => 'OR'
// ПОИСК ПО ПОЛЯМ ПОЛЬЗОВАТЕЛЬСКИХ ТИПОВ ЗАПИСЕЙ "reports"
,array(
'key' => 'report_content',
'value' => "$SEARCH",
'compare' => 'LIKE'
)
,array(
'key' => 'report_details',
'value' => "$SEARCH",
'compare' => 'LIKE'
)
// ПОИСК ПО ПОЛЯМ ПОЛЬЗОВАТЕЛЬСКИХ ТИПОВ ЗАПИСЕЙ "events"
,array(
'key' => 'event_brief',
'value' => "$SEARCH",
'compare' => 'LIKE'
)
)
);
Что я пытаюсь сделать выше – это искать слово в переменной $SEARCH внутри этих пользовательских полей.
РЕДАКТИРОВАТЬ: Просто добавлю, что индивидуальные отдельные запросы работают. Но вместо того, чтобы вызывать WP_Query
три раза, я хотел бы объединить их в один. Я изучил множество постов на Stack Overflow на тему “Я хочу объединить meta_query и tax_query”, но кажется ни один из них не касается объединения разных типов записей в условии OR, как это нужно для поиска на сайте. Три из них, которые работают индивидуально:
// ОСНОВНОЙ ЗАПРОС
$args = array(
's' => $SEARCH
,'orderby' => 'relevance'
,'post_type' => array('page', 'services', 'resources', 'events', 'reports', 'posts')
,'post_status' => 'publish'
,'posts_per_page' => 15
);
// ПОИСК ПО REPORTS
$args2 = array(
'post_type' => 'reports'
,'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'report_content',
'value' => "$SEARCH",
'compare' => 'LIKE',
),
array(
'key' => 'report_details',
'value' => "$SEARCH",
'compare' => 'LIKE',
),
),
);
// ПОИСК ПО EVENTS
$args3 = array(
'post_type' => 'events'
,'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'event_brief',
'value' => "$SEARCH",
'compare' => 'LIKE',
),
array(
'key' => 'event_instruction',
'value' => "$SEARCH",
'compare' => 'LIKE',
),
),
);
Но объединение их этим топорным способом:
$wp_query = new WP_Query( $args);
$wp_query2 = new WP_Query( $args2);
$wp_query3 = new WP_Query( $args3);
$posts = $wp_query->posts;
$posts2 = $wp_query2->posts;
$posts3 = $wp_query3->posts;
$posts = array_unique( array_merge(
$posts
,$posts2
,$posts3
) );
Не работает. Выдает печальную ошибку:
Uncaught Error: Object of class WP_Post could not be converted to string
В любом случае, я хотел бы объединить эти meta_query
с условием OR между ними. Я нашел несколько примеров meta_query, но они предполагают AND… как если бы все эти meta_query должны были совпадать. Это не то, что мне нужно. Большое спасибо.
Нашел способ объединить записи WP_Query:
$query1 = new WP_Query($args);
$query2 = new WP_Query($args2);
$query3 = new WP_Query($args3);
$combined = new WP_Query();
$combined->posts = array_merge(
$query1->posts
,$query2->posts
,$query3->posts
);
Все еще не так элегантно, как выполнение одного WP_Query с всеми этими условиями в аргументах как OR… то есть, запрос должен соответствовать ЛЮБОМУ из этих вариантов в meta_query.
Также, каким-то образом обертка array_unique()
к array_merge()
выдает ошибку.
Ответ или решение
Создание более интеллектуального поиска в WordPress, включающего пользовательские поля, возможно с использованием WP_Query, но требует тщательной настройки параметров запроса. Рассмотрим как это сделать с учетом специфики задачи, избегая использование фильтров, действий и плагинов, а также поддерживая мультиязычность через PolyLang.
Основные шаги для расширенного поиска в WP_Query
-
Правильная настройка аргументов WP_Query: Для успешного поиска через пользовательские поля необходимо корректно настроить
meta_query
. Это позволит вам искать ключевые слова внутри определенных пользовательских полей для всех указанных типов записей. -
Интеграция поиска по нескольким пользовательским полям: Важным аспектом является использование оператора
OR
внутриmeta_query
. Это позволит объединить критерии поиска по разным пользовательским полям, не требуя совпадения всех критериев одновременно.
Пример кода
$SEARCH = $_GET['s'];
$args = array(
's' => $SEARCH,
'orderby' => 'relevance',
'post_type' => array('page', 'services', 'resources', 'events', 'reports', 'posts'),
'post_status' => 'publish',
'posts_per_page' => 15,
'meta_query' => array(
'relation' => 'OR',
// Найти совпадения в пользовательских полях для всех типов записей
array(
'relation' => 'OR',
array(
'key' => 'report_content',
'value' => $SEARCH,
'compare' => 'LIKE',
),
array(
'key' => 'report_details',
'value' => $SEARCH,
'compare' => 'LIKE',
),
array(
'key' => 'event_brief',
'value' => $SEARCH,
'compare' => 'LIKE',
),
array(
'key' => 'event_instruction',
'value' => $SEARCH,
'compare' => 'LIKE',
),
),
),
);
$search_query = new WP_Query($args);
Решение проблем и оптимизация
-
Объединение результатов: Если хотите объединить результаты из нескольких WP_Query, используйте одинаковый массив
posts
для сборки конечного массива постов. Некорректное использованиеarray_merge
иarray_unique
может привести к ошибкам преобразования объектов. -
Улучшение производительности: Проверьте ограничение на количество записей в
posts_per_page
и убедитесь в его разумности. Это гарантирует скорость загрузки и стабильность работы на высоких нагрузках. -
Использование PolyLang: Убедитесь, что используете соответствующие языковые таксономии, чтобы ограничивать поиск записями на выбранном языке.
Заключение
Этот подход к WP_Query позволяет добиться более гибкого и комплексного поиска в WordPress, полностью базирующегося на возможностях встроенного API, без использования сторонних решений. Используйте мощные возможности meta_query
и осмысленные настройки параметров для достижения требуемых результатов поиска.