В WordPress часто возникает задача сформировать запросы к базе данных с несколькими условиями, которые включают фильтрацию по мета-данным, таксономиям, дате и другим параметрам одновременно. В этой статье я расскажу, как построить комплексные WP_Query с фильтрами, которые помогут получить именно те записи, которые нужны, без лишних запросов и нагрузки на сервер.
Основы WP_Query и параметры фильтрации
WP_Query — это класс в WordPress, который позволяет гибко формировать запросы к базе данных для получения постов и других типов записей. В простых случаях достаточно указать тип поста или категорию, но для более сложных задач нужны дополнительные параметры, такие как meta_query, tax_query, date_query и объединение их в один запрос.
Например, чтобы вывести все записи с мета-ключом price, больше 1000, и с категорией sale, нужно использовать сразу несколько массивов фильтрации.
Пример базового запроса с мета-фильтром
$args = [
'post_type' => 'product',
'meta_query' => [
[
'key' => 'price',
'value' => 1000,
'compare' => '>',
'type' => 'NUMERIC'
]
]
];
$query = new WP_Query($args);Этот код выведет все товары с ценой больше 1000. Но если добавить таксономию, то для объединения условий нужно использовать tax_query.
Фильтрация по нескольким таксономиям с условием AND/OR
Для фильтрации по нескольким таксономиям одновременно в WP_Query используется параметр tax_query. Он представляет собой массив условий, где можно указать логику объединения (relation) — AND или OR.
Допустим, нужно получить записи, которые относятся одновременно к категориям news И тегам featured:
$args = [
'post_type' => 'post',
'tax_query' => [
'relation' => 'AND',
[
'taxonomy' => 'category',
'field' => 'slug',
'terms' => ['news']
],
[
'taxonomy' => 'post_tag',
'field' => 'slug',
'terms' => ['featured']
]
]
];
$query = new WP_Query($args);Если нужно, чтобы записи подходили хотя бы под одно из условий, меняем relation на OR. Это гибкий инструмент для построения сложных условий выборки.
Сложные запросы с объединением meta_query, tax_query и date_query
Самое мощное — объединять несколько видов фильтров в одном запросе, например, получить товары, у которых цена больше 5000, которые находятся в категории «электроника» и опубликованы после 1 января 2023 года.
$args = [
'post_type' => 'product',
'meta_query' => [
[
'key' => 'price',
'value' => 5000,
'compare' => '>',
'type' => 'NUMERIC'
]
],
'tax_query' => [
[
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => ['electronics']
]
],
'date_query' => [
[
'after' => '2023-01-01',
'inclusive' => true
]
]
];
$query = new WP_Query($args);Такой запрос позволяет получить очень точный набор записей и подходит для создания каталогов, фильтров на сайте, отчетов и статистики.
Как улучшить производительность сложных запросов
При работе с meta_query и tax_query важно помнить, что они могут нагружать базу данных. Чтобы ускорить запросы, советую:
- Использовать индексацию нужных мета-ключей и таксономий на уровне базы данных.
- Кешировать результаты запросов с помощью Transients API или внешних кешей.
- Минимизировать количество условий, если это возможно, объединять условия в один meta_query с relation.
Пример функции для комплексного запроса с фильтрами — wpload_get_filtered_posts
Для удобства можно создать свою функцию, которая будет принимать параметры фильтра и возвращать WP_Query с нужным запросом.
function wpload_get_filtered_posts($args = []) {
$defaults = [
'post_type' => 'post',
'meta_query' => [],
'tax_query' => [],
'date_query' => []
];
$query_args = wp_parse_args($args, $defaults);
// Добавляем relation для meta_query и tax_query, если это массив и не пустой
if (!empty($query_args['meta_query']) && !isset($query_args['meta_query']['relation'])) {
$query_args['meta_query']['relation'] = 'AND';
}
if (!empty($query_args['tax_query']) && !isset($query_args['tax_query']['relation'])) {
$query_args['tax_query']['relation'] = 'AND';
}
return new WP_Query($query_args);
}Использовать функцию удобно:
$filtered_posts = wpload_get_filtered_posts([
'post_type' => 'product',
'meta_query' => [
[
'key' => 'price',
'value' => 1000,
'compare' => '>',
'type' => 'NUMERIC'
]
],
'tax_query' => [
[
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => ['sale']
]
],
'date_query' => [
[
'after' => '2023-01-01'
]
]
]);
if($filtered_posts->have_posts()) {
while($filtered_posts->have_posts()) {
$filtered_posts->the_post();
echo '<h2>' . get_the_title() . '</h2>';
}
wp_reset_postdata();
}Плагины для создания сложных фильтров на сайте
Если вы не хотите программировать самостоятельно, можно использовать готовые решения. Например, плагин Clearfy Pro предлагает расширенные настройки для оптимизации и фильтрации контента, включая работу с запросами.
Еще одна полезная опция — плагин для AJAX-фильтров, который позволяет пользователям динамически выбирать параметры и видеть результаты без перезагрузки страницы. Для интеграции с WP_Query потребуется добавить соответствующую логику в шаблоны и обработчики AJAX-запросов.
Пример AJAX-фильтра для комплексного запроса
Ниже простой пример, как организовать AJAX-запрос для фильтрации товаров по цене и категории.
add_action('wp_ajax_wpload_filter_products', 'wpload_ajax_filter_products');
add_action('wp_ajax_nopriv_wpload_filter_products', 'wpload_ajax_filter_products');
function wpload_ajax_filter_products() {
$price_min = isset($_POST['price_min']) ? intval($_POST['price_min']) : 0;
$category = isset($_POST['category']) ? sanitize_text_field($_POST['category']) : '';
$args = [
'post_type' => 'product',
'meta_query' => [
[
'key' => 'price',
'value' => $price_min,
'compare' => '>=',
'type' => 'NUMERIC'
]
],
];
if ($category) {
$args['tax_query'] = [
[
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => [$category]
]
];
}
$query = new WP_Query($args);
if ($query->have_posts()) {
while ($query->have_posts()) {
$query->the_post();
echo '<div>' . get_the_title() . ' - ' . get_post_meta(get_the_ID(), 'price', true) . '</div>';
}
wp_reset_postdata();
} else {
echo '<div>Товары не найдены</div>';
}
wp_die();
}Этот код можно привязать к JavaScript-обработчику формы фильтра на фронтенде и получить быстрый отклик от сервера.
Итоговые рекомендации
Комплексные фильтрации в WordPress — мощный инструмент для создания удобных каталогов, интернет-магазинов и новостных порталов. Правильное использование meta_query, tax_query и date_query позволяет добиться точного результата без излишней нагрузки на базу.
Не забывайте тестировать запросы на производительность, кешировать результаты и использовать готовые плагины, если не хотите писать все вручную.