selftrips
@selftrips

Как написать запрос в базу wordpress?

Для элемента 1 (id1 этого элемента ) таксономии1 (id_t1) получиться список постов (id2) в которые он входит (или наоборот в него входят, не знаю как правильно говорить), для этого списка постов, получить список (id3) таксономии2 (id_t2)
  • Вопрос задан
  • 236 просмотров
Решения вопроса 1
HeadOnFire
@HeadOnFire
PHP, Laravel & WordPress Evangelist
1. Получить ID постов в конкретной категории:
$args = array(
    'post_type' => 'post', // изолируем нужный post type
    'post_status' => 'publish', // изолируем только опубликованные записи
    'category__in' => array( 15 ), // где 15 - ID вашей категории
    'posts_per_page' => -1, // забираем все посты, отвечающие требованиям
    'fields' => 'ids', // возвращаем только массив ID найденных записей
    'cache_results' => true, // кешируем полученные результаты
    'no_found_rows' => true, // не считаем общее количество найденных записей
    'update_post_meta_cache' => false, // не забираем и не кешируем метаданные для этих записей
    'update_post_term_cache' => false, // не забираем и не кешируем термины для этих записей
);
$posts_in_category = new WP_Query( $args );

Половина $args - это оптимизация и ускорение запроса. Получаем только необходимые данные, не запрашиваем, не обрабатываем и не кешируем то, что нам вообще не нужно. Задача - получить и закешировать только массив ID записей, которые имеют нужную категорию. Все это есть в документации.

2. Получаем теги, которые используются данными постами (полученными выше):
$args = array(
    'taxonomy' => 'post_tag', // изолируем нужную таксономию
    'object_ids' => $posts_in_category->posts, // получаем только теги, которые присвоеные объектам с этими ID
    'update_term_meta_cache' => false, // true|false - получать ли (и кешировать ли) метаданные терминов
);
$tags_in_posts = get_terms( $args );

На выходе у вас будет массив тегов. Дополнительные параметры можете смотреть тут. Собственно, вместо get_terms() можете использовать WP_Term_Query.

UPDATE:

Допустил ошибку в коде, строчка 'object_ids' => $posts_in_category, должна быть 'object_ids' => $posts_in_category->posts, - ибо переменная будет содержать объект WP_Query, а уже свойство posts будет содержать ID найденных постов.

Еще один важный нюанс и еще одна ошибка - если категорию включать с помощью параметра 'cat', то запрос по умолчанию будет выполнен с параметром 'include_children' => true, что нам не нужно, ибо исказит результат и включит ненужные посты. Переписал и этот фрагмент - вместо использования стандартного параметра 'cat' теперь используем 'category__in' - это включит только посты, которым назначена именно эта категория.

Что касается количества выполненных запросов:

WP_Query выполнит только 1 запрос:

SELECT wp_posts.ID
FROM wp_posts 
LEFT JOIN wp_term_relationships
ON (wp_posts.ID = wp_term_relationships.object_id)
WHERE 1=1 
AND ( wp_term_relationships.term_taxonomy_id IN (2) )
AND wp_posts.post_type = 'post'
AND ((wp_posts.post_status = 'publish'))
GROUP BY wp_posts.ID
ORDER BY wp_posts.post_date DESC


В данном коде 2 = ID категории на моем тестовом сайте. На выходе получается Х постов, которым назначена именно эта категория.

Далее, get_terms выполнит тоже всего 1 запрос:

SELECT t.*, tt.*
FROM wp_terms AS t 
INNER JOIN wp_term_taxonomy AS tt
ON t.term_id = tt.term_id
INNER JOIN wp_term_relationships AS tr
ON tr.term_taxonomy_id = tt.term_taxonomy_id
WHERE tt.taxonomy IN ('post_tag')
AND tr.object_id IN (19, 15, 13, 1)
ORDER BY t.name ASC


В данном коде 19, 15, 13, 1 - это и есть ID постов, которые мы получили первым запросом. Таким образом, будут получены только термины таксономии post_tag, которые назначены этим конкретным постам.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы