Intersección eficiente de taxonomía

9

Tengo muchos usos para esto, pero quiero conocer la forma más eficaz de hacer lo que será una operación costosa.

Como ejemplo usaré una tienda.

Dado:

  • Una taxonomía de marca de producto
  • Una taxonomía de grupo de productos
  • Un tipo de publicación de producto
  • Plantillas de archivo para las taxonomías anteriores

¿Cuál es el método más eficaz y eficaz para mostrar un menú de marca en un archivo de tipo de producto y un tipo de producto en un archivo de marca, pero solo mostrar los términos que se aplican a las publicaciones de ese grupo?

Entonces, por ejemplo, si estoy en el grupo de productos 'mujeres', mostraría marcas en el lado izquierdo, pero solo las marcas especificadas para productos en el grupo de productos 'mujeres'. Por ejemplo, la marca 'Fancy womens clothes Inc' mostraría, pero no 'Manly mens Manly ltd'.

Necesito una respuesta genérica, aunque estoy feliz de que se use el ejemplo de los productos de ropa, y sé cómo hacerlo con un algoritmo codicioso por fuerza bruta, pero eso es increíblemente derrochador, y no estoy interesado en una solución que aumentaría cada carga de la página en varios segundos y cargaría todas las publicaciones en su totalidad desde la base de datos en el proceso

editar: Ejemplo 2:

Pikachu es un pokemon amarillo, y está en la etiqueta amarilla, pero Pikachu también es un pokemon eléctrico, por lo que está en la etiqueta eléctrica de la taxonomía tipo. ¿Cómo mostraría solo los tipos de pokemon que son amarillos cuando están en el archivo de etiquetas amarillas? por ejemplo, todos los pokemon de hierba son verdes significa que no habrá un elemento de menú de hierba cuando esté en el archivo amarillo, pero sí en el verde (sí, sé que hay pokemon de hierba que no son verdes)

Tom J Nowell
fuente

Respuestas:

12

Para generalizar, se trata de recuperar todos los términos de la taxonomía A que se publican con un término específico de la taxonomía B.

Si bien esto no es imposible en varios pasos y un montón de bucles a través de publicaciones (lo que de hecho será ineficiente), creo que es razonable pasar por SQL para lograr eficiencia.

Mi opinión aproximada sería:

/**
 * 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
fuente