Получить список терминов текущего архива таксономии для другой таксономии.

Вопрос или проблема

У меня есть пользовательский тип записи с названием ‘Real estate’, который имеет (среди прочего) две разные таксономии:

  • ‘Purpose’ (иерархическая; используемые термины: ‘Living’, ‘Working’ и ‘Holidays’) и
  • ‘Location’ (неиерархическая; например, ‘London’, ‘Berlin’, ‘Paris’).

Для формы поиска в архиве таксономии ‘Living’ мне нужен список всех терминов ‘Location’, связанных с записями в архиве термина таксономии ‘Living’, чтобы вернуть его через селектор в форме поиска. Как я могу, лучше всего в виде списка значений, разделённых запятыми для массива, получить все термины для ‘Location’, использованные в архиве термина ‘Living’?

Ладно, мне кажется, у меня есть что-то для вас! Как вы знаете, у меня была такая же проблема, и когда я перебирал каждую таксономию, я обнаружил, что генерирую от 25 до 35 запросов, что безумие! Поэтому я решил попробовать работать с некоторыми запросами MySQL в таблице отношений терминов, чтобы посмотреть, нет ли более быстрого способа запрашивать данные.

С помощью отличного разработчика, которого я знаю (Mac McDonald http://wordpress.mcdspot.com/), я создал функцию, которая делает один запрос и возвращает массив идентификаторов терминов в “другой” таксономии. Сначала вам нужно подготовить идентификаторы терминов для запроса, вот так:

//таксономия, для которой мы хотим проверить термины
$opposite_taxonomy_terms = get_terms( $taxonomy );

//новый массив, с текущим идентификатором термина, очень важно!
$sibling_term_ids = array( $this_term->term_id );

foreach( $opposite_taxonomy_terms as $term )
{
    //собираем все идентификаторы, готовые для создания запроса MySQL
    $sibling_term_ids[] = $term->term_id;

}

$imploded = implode(', ', $sibling_term_ids );

$results = rd_get_opposite_terms( $imploded, $this_term->term_id );

Я получаю термины, которые хочу “проверить”, и затем добавляю их в массив, который должен содержать основной идентификатор термина, по которому выполняется запрос. Затем я конкатенирую их, чтобы получить список, разделённый запятыми, для запроса MySQL. Это находится в функции rd_get_opposite_terms();

function rd_get_opposite_terms( $imploded = array(), $current_term_id = FALSE )
{
    if( empty( $imploded ) || ! $current_term_id )
        return FALSE;

    global $wpdb;

    //выполняем запрос, чтобы найти термины, у которых есть записи как в $current_term_id (из одной таксономии), так и в терминах $imploded (идентификаторы терминов из другой таксономии). Возвращает идентификаторы в виде массива.
    return $wpdb->get_col( 'SELECT tr1.term_taxonomy_id FROM wp_term_relationships tr1 WHERE tr1.term_taxonomy_id IN ( ' . $imploded . ' ) AND tr1.object_id IN (SELECT DISTINCT object_id FROM wp_term_relationships tr2 WHERE tr2.term_taxonomy_id = ' . $current_term_id . ' ) GROUP BY tr1.term_taxonomy_id' );
}

Признаюсь, это почти предел моих возможностей разработки на данный момент, но я думаю, это гораздо лучшее решение, чем то, что у меня было изначально, и надеюсь, оно поможет и вам!

Ответ или решение

Ваша задача состоит в том, чтобы получить список терминов таксономии “Локация”, которые ассоциированы с постами в термине “Жильё” таксономии “Цель”. Вы хотите использовать эти данные в поисковой форме для отображения в виде списка с возможностью выбора. Для решения этой задачи можно оптимизировать запросы к базе данных, используя один запрос MySQL, который бы возвращал все необходимые термины в одном из запросов.

Шаги для решения задачи:

  1. Подготовка терминов для запроса:

    • Первоначально, вы извлекаете все термины таксономии, с которой хотите работать (get_terms()), например, "Цель".
    • Создайте массив идентификаторов терминов, включая идентификатор текущего термина, который вас интересует.
  2. Создание MySQL запроса:

    • Используйте массив идентификаторов терминов для построения списка через implode(). Это создаст строку из чисел, разделённых запятыми, которая будет использоваться в запросе.
    • Далее создайте функцию rd_get_opposite_terms(), которая выполнит MySQL запрос для получения терминов таксономии "Локация", связанных с вашими условиями.
  3. Запрос и получение данных:

    • Выполняется запрос к базе данных, который извлекает ID терминов таксономии "Локация", где объект идентичен объекту из термины "Жильё" таксономии "Цель".
    • Запрос использует аргумент группы GROUP BY для получения уникальных терминов.

Пример кода:

function rd_get_opposite_terms($imploded = array(), $current_term_id = FALSE)
{
    if (empty($imploded) || !$current_term_id)
        return FALSE;

    global $wpdb;

    return $wpdb->get_col('SELECT tr1.term_taxonomy_id 
                           FROM wp_term_relationships tr1 
                           WHERE tr1.term_taxonomy_id IN (' . $imploded . ') 
                           AND tr1.object_id IN (SELECT DISTINCT object_id 
                                                FROM wp_term_relationships tr2 
                                                WHERE tr2.term_taxonomy_id = ' . $current_term_id . ') 
                           GROUP BY tr1.term_taxonomy_id');
}

Рекомендации:

  • Убедитесь, что используете wpdb->prepare() для защиты от SQL-инъекций, если переменные передаются в запрос напрямую.
  • Подумайте о кэшировании результатов запроса, чтобы уменьшить нагрузку на базу данных при повторных запросах.

Эта методика позволяет значительно сократить количество запросов к базе данных и повысить производительность вашего WordPress сайта. Надеюсь, что вы найдете это решение полезным и эффективным для вашей задачи.

Оцените материал
Добавить комментарий

Капча загружается...