Вопрос или проблема
Я создал пользовательский файл .php, который должен показывать список всех записей, соответствующих выбору пользователя. У меня есть 3 пользовательских поля и 1 условие категории.
Я попробовал все запросы, которые только мог найти в базе данных codex wordpress, но ничего не работает.
Я создал 3 пользовательских поля: a_field, a_fieldd, a_fielddd (и, конечно, у меня уже есть записи с этими полями для теста), теперь я просто хочу показать все записи с пользовательскими полями с указанными значениями (выбор пользователя) и только если эти записи находятся в выбранной категории.
ИЗМЕНЕНИЕ
У меня есть запрос (с всего 1 значением для теста), который, похоже, работает, но иногда занимает 0,00002 секунды, а иногда до 4 секунд. Какие предложения? Я знаю, что было бы лучше использовать wp_query, но я нашел этот способ более простым для изменения.
В этом примере я пытаюсь получить запись с meta_key a_field со значением “5”.
SELECT wp_posts.ID FROM wp_posts
INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id)
INNER JOIN wp_postmeta ON (wp_posts.ID = wp_postmeta.post_id)
INNER JOIN wp_postmeta AS mt1 ON (wp_posts.ID = mt1.post_id)
INNER JOIN wp_postmeta AS mt2 ON (wp_posts.ID = mt2.post_id)
WHERE 1=1 AND wp_posts.post_type="post"
AND wp_posts.post_status="publish"
AND ( (wp_postmeta.meta_key = 'a_field'
AND find_in_set('5',wp_postmeta.meta_value)) )
GROUP BY wp_posts.ID ORDER BY wp_posts.post_date DESC LIMIT 0, 10
Какие предложения?
Для обработки нескольких категорий вам нужен либо category__in
, либо tax_query
, для нескольких пользовательских полей вы используете meta_query
. Различные опции для обоих из них охватываются на WP_Query
codex странице.
$args = array(
'posts_per_page' => 10,
'category__in' => array( 163, 165 ),
'meta_query' => array(
array(
'key' => 'a_field',
'value' => array( 1, 2 ),
'compare' => 'IN'
),
array(
'key' => 'a_fieldd',
'value' => 3,
'compare' => '='
),
array(
'key' => 'a_fielddd',
'value' => array( 1, 3, 5 ),
'compare' => 'IN'
)
)
);
$results = new WP_Query( $args );
if( $results->have_posts() ){
while( $results->have_posts() ){
$results->the_post();
the_title();
}
}
Ответ или решение
Запрос на получение постов с учетом пользовательских полей и категорий
Вам необходимо создать запрос, который будет возвращать список постов на основе заданных значений пользовательских полей и определенной категории. Это часто встречающаяся задача в WordPress, и для её решения удобно использовать класс WP_Query
, который предоставляет более гибкие и оптимизированные способы работы с базой данных.
Оптимизация производительности запроса
Ваш изначальный SQL-запрос может быть неэффективным из-за необходимости выполнения соединений (JOIN) и возможного использования GROUP BY
, что может значительно увеличивать время выполнения запроса, особенно на больших базах данных. Использование WP_Query
автоматически устраняет некоторые из этих проблем, и запросы при этом будут выполняться более последовательно и быстро.
Пример использования WP_Query
Для получения постов на основе нескольких пользовательских полей и категории, вы можете использовать следующий код:
$args = array(
'posts_per_page' => 10, // Количество постов на вывод
'category__in' => array(163, 165), // Укажите ID категорий
'meta_query' => array(
'relation' => 'AND', // Условия по умолчанию "AND"
array(
'key' => 'a_field',
'value' => array(1, 2), // Значения для поиска
'compare' => 'IN' // Использовать сравнение IN
),
array(
'key' => 'a_fieldd',
'value' => 3, // Значение для следующего поля
'compare' => '=' // Использовать сравнение равно
),
array(
'key' => 'a_fielddd',
'value' => array(1, 3, 5), // Дополнительные значения
'compare' => 'IN' // И снова, сравнение IN
)
)
);
$results = new WP_Query($args);
if ($results->have_posts()) {
while ($results->have_posts()) {
$results->the_post(); // Подготовка данных о посте
the_title(); // Вывод заголовка поста
}
}
wp_reset_postdata(); // Сброс глобальной переменной $post
Пояснения к коду
posts_per_page
: Указывает количество постов, которые вы хотите получить.category__in
: Позволяет фильтровать посты по массиву ID категорий. Если вам нужно добавить больше категорий, просто добавьте их в массив.meta_query
: Для фильтрации постов по пользовательским полям. Обратите внимание на использованиеrelation
, который может быть установлен вAND
илиOR
, в зависимости от ваших требований.the_title()
: Вернет заголовок каждого поста. Вы можете модифицировать вывод, чтобы отображать другие атрибуты постов по мере необходимости.wp_reset_postdata()
: Важно использовать эту функцию послеWP_Query
, чтобы сбросить глобальную переменную$post
и избежать потенциальных конфликтов с другими запросами.
Рекомендации по производительности
- Кэширование данных: Рассмотрите возможность интеграции кэширования для часто запрашиваемых данных, которое снизит нагрузку на базу данных.
- Индексация пользовательских полей: Эффективное индексирование таблицы
wp_postmeta
поможет улучшить время выполнения запросов, если у вас много данных. - Асинхронные запросы: Для улучшения пользовательского опыта можете рассмотреть возможность выполнения запросов асинхронно через AJAX, что позволит загружать данные динамически, не перезагружая страницу.
Таким образом, предложенный подход позволяет эффективно извлекать необходимые данные из базы, учитывая пользовательские поля и категории. Важно поддерживать код чистым и оптимизированным, чтобы снизить время загрузки и улучшить общую производительность сайта.