Эффективное пересечение таксономии

9

У меня есть много применений для этого, но я хочу знать наиболее эффективный способ сделать то, что будет дорогой операцией.

В качестве примера я буду использовать магазин.

Данный:

  • Таксономия бренда продукта
  • Таксономия группы продуктов
  • Тип поста продукта
  • Архивные шаблоны для вышеуказанных таксономий

Каков наиболее эффективный и эффективный способ отображения меню бренда в архиве типа продукта и типа продукта в архиве бренда, но при этом отображаются только те термины, которые относятся к публикациям в этой группе.

Так, например, если я нахожусь в группе товаров «женские», на левой стороне будут отображаться бренды, но только те бренды, которые указаны для продуктов в группе «женские». Например, показывался бы бренд «Fancy womens clothes Inc», но не «Manly mens Manly ltd».

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

редактировать: пример 2:

Пикачу - это желтый покемон, и он находится в желтом теге, но Пикачу также является электрическим покемоном, поэтому он находится в электрическом теге таксономии типа. Как бы я показал только те типы покемонов, которые желтые в архиве желтых тегов? например, если все зеленые травяные покемоны означают, что в желтом архиве не будет пункта меню травы, но будет в зеленом (да, я знаю, что есть зеленые травяные покемоны)

Том Дж Новелл
источник

Ответы:

13

Обобщая, это проблема извлечения всех терминов таксономии A, которые имеют посты с определенным термином таксономии B.

Хотя это не невозможно в несколько этапов и большое количество циклически повторяющихся сообщений (что действительно будет неэффективно), я думаю, что для эффективности целесообразно пройти через SQL.

Мой грубый взгляд на это будет:

/**
 * Get all terms of $tax_to taxonomy that posts in $term_from of $tax_from have.
 *
 * @param string $tax_from  taxonomy name
 * @param string $term_from term slug
 * @param string $tax_to    taxonomy name
 *
 * @return array|WP_Error
 */
function get_intersected_terms( $tax_from, $term_from, $tax_to ) {

    global $wpdb;

    $term_from = get_term_by( 'slug', $term_from, $tax_from );

    $query = "
    SELECT term_id FROM {$wpdb->term_taxonomy} WHERE taxonomy = '{$tax_to}' AND term_taxonomy_id IN (
        SELECT term_taxonomy_id FROM {$wpdb->term_relationships} WHERE object_id IN (
            SELECT object_id FROM {$wpdb->term_relationships} WHERE term_taxonomy_id = {$term_from->term_taxonomy_id}
        )
    )
    ";

    $term_ids = $wpdb->get_col( $query );

    if( empty( $term_ids) )
        return array();

    return get_terms( $tax_to, array( 'include' => $term_ids ) );
}

// example
var_dump( get_intersected_terms( 'category', 'cat-a', 'post_tag' ) );
Rarst
источник