Obțineți ultimul post din fiecare categorie într-o singură interogare
Blogul meu WordPress are 12 categorii principale și 80 subcategorii.
Trebuie să obțin ultimul post din fiecare dintre acele 12 categorii.
Știu cum să fac acest lucru cu 12 interogări folosind get_posts(), dar există vreo metodă să obțin rezultatele într-o singură interogare?
Am încercat această soluție, dar returnează mai mult de 12 postări:
// Obține un array cu categorii (doar nivelul 0)
$cats= array();
$categories=get_categories($args);
foreach($categories as $category) {
if ($category->parent == 0) {
$cats[]= $category->term_id ;
}
}
$categories= implode(',',$cats);
// Obține ultima postare din fiecare categorie
global $wpdb;
$querystr = "SELECT wposts.*
FROM $wpdb->posts wposts
LEFT JOIN $wpdb->term_relationships ON (wposts.ID = $wpdb->term_relationships.object_id)
LEFT JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)
WHERE $wpdb->term_taxonomy.taxonomy = 'category'
AND $wpdb->term_taxonomy.term_id IN($categories)
ORDER BY wposts.post_date DESC";
$pageposts = $wpdb->get_results($querystr, OBJECT);
Și apoi bucla:
global $post;
foreach ($pageposts as $k=>$post):
setup_postdata($post);
// ... bucla standard WordPress prin rezultate
}
Cantitatea de interogări nu este singurul indicator de performanță, o singură interogare poate fi mai costisitoare decât mai multe interogări simple.
Costul a (interogare mică) x12 < costul unei interogări mari x1 + manipularea string-urilor/tablourilor
Ar fi mai bine să faci cele 12 interogări individuale. Dacă este costisitor, stochează rezultatul într-un transient pentru utilizare ulterioară și economisește procesarea.
Dar și mai bine, ai putea actualiza valorile folosind un hook pe save_post astfel încât să nu fie nevoie de nicio 'căutare', iar operația devine doar o simplă preluare a unei valori stocate. În acest fel, dacă o stochezi și o obții via get_option, nu vor fi executate interogări suplimentare deoarece WordPress a încărcat deja valoarea și nu va face o interogare SQL inutilă pentru a o prelua a doua oară.
// în functions.php
function verifica_ultima_categorie($post_id){
// verifică categoriile asignate acestui articol
// pentru fiecare categorie asignată
// dacă este cea mai recentă în acea categorie
set_option('mytheme_cat_'.$term_id,$post_id);
}
add_hook('save_post','verifica_ultima_categorie');
// unde vrei să afișezi articolele
$categories=get_categories($args);
foreach($categories as $category) {
$post_id = get_option('mytheme_cat_'.$category->term_id);
// afișează articolul
}
Ceva de genul acesta îți va oferi ceea ce dorești, și va funcționa pentru toate subcategoriile, fiind mult mai eficient decât 12 interogări individuale sau chiar o singură interogare mare și costisitoare.
