web-dev-qa-db-ja.com

効率的な分類法の交点

これには多くの用途がありますが、高価な操作になることを最も効率的に行う方法を知りたいです。

例として、私は店を使います。

与えられた:

  • 製品ブランド分類
  • 製品グループ分類
  • 商品投稿タイプ
  • 上記の分類法のアーカイブテンプレート

商品タイプアーカイブのときにブランドメニューを表示し、ブランドアーカイブのときに商品タイプを表示する、最も効率的でパフォーマンスの高い方法は何ですか。ただし、そのグループの投稿に適用される用語のみを表示します。

したがって、たとえば、私が製品グループ「女性」の場合、左側にブランドが表示されますが、「女性」製品グループの製品に指定されているブランドのみが表示されます。例えば。ブランド「Fancy womens clothes Inc」は表示されますが、「Manly mens Manly ltd」は表示されません。

私は一般的な答えを必要としていますが、私は衣料品の例を使用するのはうれしいし、ブルートフォースによる貪欲なアルゴリズムでこれを行う方法を知っていますが、それは信じられないほど無駄です。すべてのページのロードが数秒増加し、その過程でDBからすべての投稿がすべてロードされます。

編集:例2:

ピカチュウは黄色のポケモンであり、黄色のタグの中にありますが、ピカチュウも電気ポケモンであるので、それはタイプ分類学の電気タグの中にあります。黄色のタグアーカイブに入っているときに黄色のポケモンの種類だけを表示するにはどうすればよいですか。例えばすべての草のポケモンが緑色であるということは、黄色のアーカイブには草のメニュー項目はないが、緑色になるということです(はい、緑色ではない草のポケモンがあることを知っています)

9
Tom J Nowell

これを一般化すると、分類学Bの特定の用語を持つ投稿が持っている分類学Aのすべての用語を検索する問題です。

これはいくつかのステップで不可能ではありませんし、投稿を何度もループすることは不可能です(実際は非効率的です)が、効率を上げるために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' ) );
12
Rarst