O que você quer é possível, mas vai exigir que você se aprofunde no SQL que eu gostaria de evitar sempre que possível (não porque eu não saiba, eu sou um desenvolvedor de SQL avançado, mas porque no WordPress, você deseja usar a API sempre que possível para minimizar futuros problemas de compatibilidade relacionados a possíveis mudanças futuras na estrutura do banco de dados.
SQL com um operador UNION
é uma possibilidade
Para usar o SQL, você precisa de um operador UNION
em sua consulta, algo como isto, supondo que suas slugs de categoria sejam "category-1"
, "category-1"
e "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
)
Você pode usar o SQL UNION com um filtro posts_join
Usando as opções acima, você pode fazer a chamada diretamente ou usar o gancho de filtro posts_join
da seguinte maneira; note que estou usando um PHP heredoc , portanto, certifique-se de que SQL;
está à esquerda. Observe também que usei um var global para permitir que você defina as categorias fora do gancho listando as slugs de categoria em um array. Você pode colocar esse código em um plug-in ou no arquivo functions.php
do seu 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 " ;
}
Mas pode haver efeitos colaterais
É claro que usar os ganchos de modificação de consulta como posts_join
sempre solicita efeitos colaterais, pois eles agem globalmente nas consultas e, portanto, você geralmente precisa incluir as modificações em um if
que só usa quando necessário e quais critérios teste para pode ser complicado.
Concentre-se na otimização em vez disso?
No entanto, suponho que sua pergunta esteja relacionada com mais sobre otimização do que com a possibilidade de fazer uma consulta top 5 de tempo 3, certo? Se for esse o caso, então talvez haja outras opções que usam a API do WordPress?
Melhor usar a API de transientes para cache?
Suponho que suas postagens não serão alteradas com frequência, correto? E se você aceitar a consulta de três (3) ocorrências periodicamente e, em seguida, armazenar os resultados em cache usando a API de transientes ? Você terá um código de fácil manutenção e ótimo desempenho; um pouco melhor que a consulta UNION
acima porque o WordPress armazenará as listas de posts como um array serializado em um registro da tabela wp_options
.
Você pode usar o seguinte exemplo e inserir a raiz do seu site como test.php
para testar:
<?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);
Resumo
Embora você possa fazer o que solicitou usando uma consulta UNION
do SQL e o gancho do filtro posts_join
, provavelmente é melhor oferecer o uso do armazenamento em cache com a API de transientes em vez disso.
Espero que isso ajude?