Lo que desea es posible pero requerirá que profundice en SQL que me gusta evitar siempre que sea posible (no porque no lo sepa, soy un desarrollador avanzado de SQL, sino porque en WordPress desea utilizar la API siempre que sea posible para minimizar futuros problemas de compatibilidad relacionados con futuros cambios potenciales en la estructura de la base de datos.)
SQL con un operador UNION
es una posibilidad
Para usar SQL, lo que necesita es un operador UNION
en su consulta, algo como esto, suponiendo que las babosas de su categoría son "category-1"
, "category-1"
y "category-3"
:
SELECT * FROM wp_posts WHERE ID IN (
SELECT tr.object_id
FROM wp_terms t
INNER JOIN wp_term_taxonomy tt ON t.term_id = tt.term_id
INNER JOIN wp_term_relationships tr ON tt.term_taxonomy_id = tr.term_taxonomy_id
WHERE tt.taxonomy='category' AND t.slug='category-1'
LIMIT 5
UNION
SELECT tr.object_id
FROM wp_terms t
INNER JOIN wp_term_taxonomy tt ON t.term_id = tt.term_id
INNER JOIN wp_term_relationships tr ON tt.term_taxonomy_id = tr.term_taxonomy_id
WHERE tt.taxonomy='category' AND t.slug='category-2'
LIMIT 5
UNION
SELECT tr.object_id
FROM wp_terms t
INNER JOIN wp_term_taxonomy tt ON t.term_id = tt.term_id
INNER JOIN wp_term_relationships tr ON tt.term_taxonomy_id = tr.term_taxonomy_id
WHERE tt.taxonomy='category' AND t.slug='category-3'
LIMIT 5
)
Puede usar SQL UNION con un posts_join
Filter
Utilizando lo anterior, puede simplemente hacer la llamada directamente o usar un gancho de filtro posts_join
de la siguiente manera; note que estoy usando un PHP heredoc así que asegúrese de que SQL;
está a la izquierda. También tenga en cuenta que utilicé una var global para permitirle definir las categorías fuera del gancho al enumerar las categorías de una barra. Puede colocar este código en un complemento o en el archivo functions.php
de su tema:
<?php
global $top_5_for_each_category_join;
$top_5_for_each_category_join = array('category-1','category-2','category-3');
add_filter('posts_join','top_5_for_each_category_join',10,2);
function top_5_for_each_category_join($join,$query) {
global $top_5_for_each_category_join;
$unioned_selects = array();
foreach($top_5_for_each_category_join as $category) {
$unioned_selects[] =<<<SQL
SELECT object_id
FROM wp_terms t
INNER JOIN wp_term_taxonomy tt ON t.term_id = tt.term_id
INNER JOIN wp_term_relationships tr ON tt.term_taxonomy_id = tr.term_taxonomy_id
WHERE tt.taxonomy='category' AND t.slug='{$category}'
LIMIT 5
SQL;
}
$unioned_selects = implode("\n\nUNION\n\n",$unioned_selects);
return $join . " INNER JOIN ($unioned_selects) categories ON wp_posts.ID=categories.object_id " ;
}
Pero puede haber efectos secundarios
Por supuesto, usar los ganchos de modificación de consulta como posts_join
siempre invita a los efectos secundarios, ya que actúan globalmente en las consultas y, por lo tanto, generalmente es necesario envolver sus modificaciones en un if
que solo lo usa cuando es necesario y los criterios para hacerlo. La prueba puede ser complicada.
¿Enfocarse en la optimización en su lugar?
Sin embargo, supongo que le preocupa su pregunta es más acerca de la optimización que de poder hacer una consulta entre los 5 primeros 3 tiempos, ¿verdad? Si ese es el caso, ¿tal vez hay otras opciones que utilizan la API de WordPress?
¿Es mejor utilizar la API de Transients para el almacenamiento en caché?
Supongo que tus publicaciones no cambiarán tan a menudo, ¿correcto? ¿Qué sucede si acepta los tres (3) resultados de consultas periódicamente y luego almacena en caché los resultados utilizando la API de transitorios ? Obtendrás un código mantenible y un gran rendimiento; un poco mejor que la consulta UNION
anterior porque WordPress almacenará las listas de publicaciones como una matriz serializada en un registro de la tabla wp_options
.
Puedes tomar el siguiente ejemplo y colocarlo en la raíz de tu sitio web como test.php
para probar esto:
<?php
$timeout = 4; // 4 hours
$categories = array('category-1','category-2','category-3');
include "wp-load.php";
$category_posts = get_transient('top5_posts_per_category');
if (!is_array($category_posts) || count($category_posts)==0) {
echo "Hello Every {$timeout} hours!";
$category_posts = array();
foreach($categories as $category) {
$posts = get_posts("post_type=post&numberposts=5&taxonomy=category&term={$category}");
foreach($posts as $post) {
$category_posts[$post->ID] = $post;
}
}
set_transient('top5_posts_per_category',$category_posts,60*60*$timeout);
}
header('Content-Type:text/plain');
print_r($category_posts);
Resumen
Mientras que sí, puede hacer lo que pidió usando una consulta SQL UNION
y el gancho de filtro posts_join
que probablemente sea mejor ofrecer usando el almacenamiento en caché con la API de transitorios en su lugar.
Espero que esto ayude?