Quello che vuoi è possibile ma ti richiederà di approfondire SQL che mi piace evitare quando possibile (non perché non lo conosco, sono uno sviluppatore SQL avanzato, ma perché in WordPress vuoi usare l'API ogni volta che è possibile per ridurre al minimo i futuri problemi di compatibilità correlati a future modifiche alla struttura del database.)
SQL con un UNION
operatore è una possibilità
Per utilizzare SQL quello che vi serve è un UNION
operatore la tua ricerca, qualcosa di simile assumendo le vostre lumache categoria sono "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
)
È possibile utilizzare SQL UNION con un posts_join
filtro
Utilizzando quanto sopra puoi semplicemente effettuare la chiamata direttamente oppure puoi usare un posts_join
hook di filtro come segue; nota che sto usando un herpoc PHP, quindi assicurati che SQL;
sia a filo. Nota anche che ho usato una var globale per permetterti di definire le categorie al di fuori del gancio elencando le lumache di categoria in un array. Puoi inserire questo codice in un plugin o nel functions.php
file del tuo 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 " ;
}
Ma ci possono essere effetti collaterali
Ovviamente usare gli hook di modifica delle query come posts_join
sempre invita gli effetti collaterali in quanto agiscono globalmente sulle query e quindi di solito è necessario racchiudere le modifiche in uno if
che le utilizza solo quando necessario e quali criteri per testare possono essere difficili.
Concentrarsi sull'ottimizzazione, invece?
Tuttavia, suppongo che la tua domanda riguardi più l'ottimizzazione che la possibilità di eseguire una query 5 con la top 5, giusto? In tal caso, forse ci sono altre opzioni che utilizzano l'API di WordPress?
Meglio usare l'API dei transitori per la memorizzazione nella cache?
Presumo che i tuoi post non cambieranno così spesso, giusto? Cosa succede se si accetta periodicamente il tre (3) hit della query e si memorizzano nella cache i risultati usando l' API Transients ? Otterrai codice gestibile e grandi prestazioni; un po 'meglio della UNION
query sopra perché WordPress memorizzerà gli elenchi di post come un array serializzato in un record della wp_options
tabella.
Puoi prendere il seguente esempio e rilasciarlo nella radice del tuo sito web test.php
per provarlo:
<?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);
Sommario
Sebbene sì, puoi fare ciò che hai richiesto utilizzando una UNION
query SQL e l' posts_join
hook del filtro che probabilmente ti è meglio offrire utilizzando la memorizzazione nella cache con l' API Transients .
Spero che sia di aiuto?