Domanda

Ho 3 categorie con ogni 15 messaggi, voglio fare una query al DB portare solo 5 primi posti per ogni categoria, come posso farlo?

$q = new WP_Query(array( 'post__in' => array(2,4,8), 'posts_per_page' => **FIRST_5_OF_EACH_CAT** ));

Nel caso in cui la sua non è possibile, ciò che è più efficiente, ottenendo tutti i posti per la categoria genitore e loop attraverso di loro o la creazione di 3 query diverse?

È stato utile?

Soluzione

Ciò che si vuole è possibile, ma richiede di approfondire SQL che mi piace di evitare, quando possibile (non perché io non lo so, io sono uno sviluppatore SQL anticipo, ma perché in WordPress si desidera utilizzare l'API quando possibile per ridurre al minimo i futuri problemi di compatibilità relativi a potenziali future modifiche alla struttura del database.)

SQL con un UNION operatore è una possibilità

Per usare SQL quello che vi serve è un operatore UNION nella query, qualcosa di simile assumendo tuoi categoria lumache 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 filtro posts_join

Utilizzando quanto sopra è possibile sia solo effettuare la chiamata diretta o puoi utilizzare un gancio di filtro posts_join come il seguente; nota sto usando un PHP heredoc in modo da assicurarsi il SQL; è allineato a sinistra. Si noti inoltre ho usato una var globale per consentire di definire le categorie al di fuori del gancio elencando le lumache categoria in un array. È possibile inserire questo codice in un plugin o nel file di functions.php del vostro 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

Naturalmente utilizzando i ganci di modifica della query come posts_join invita sempre effetti collaterali in quanto agiscono a livello globale su query e quindi è di solito necessario per avvolgere le modifiche in un if che solo lo usa quando necessario e quali criteri di prova per può essere ingannevole.

Focus su Ottimizzazione Invece?

Tuttavia, presumo la tua domanda è interessato è di più su ottimizzazione di di essere in grado di fare un top 5 Tempo 3 di query, giusto? Se questo è il caso allora forse ci sono altre opzioni che utilizzano l'API di WordPress?

meglio usare transitori API per Caching?

Presumo i tuoi messaggi non cambieranno spesso, giusto? Che cosa succede se si accetta il tre (3) interrogazione colpito periodicamente e quindi memorizzare nella cache i risultati utilizzando il transitori API ? Otterrete il codice mantenibile e grandi prestazioni; un bel po 'migliore rispetto alla query UNION sopra, perché WordPress memorizza l'elenco dei posti come un array serializzato in un record della tabella wp_options.

Si può prendere il seguente esempio e cadere nel principale del sito web come test.php per testare il tutto:

<?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

Mentre sì, si può fare quello che hai chiesto per l'utilizzo di una query SQL UNION e il gancio del filtro posts_join si sono probabilmente meglio offrite utilizzando la cache con il transitori API , invece.

Spero che questo aiuti?

Altri suggerimenti

WP_Query() non supporta qualcosa come In primo luogo X per ogni gatto . Invece di WP_Query() è possibile utilizzare get_posts() su ciascuna delle vostre categorie, per così dire tre volte:

<?php
$posts      = array():
$categories = array(2,4,8);
foreach($categories as $cat) {
  $posts[] = get_posts('numberposts=5&offset=1&category='.$cat);
}
?>

$posts ora contiene i primi cinque posti per ogni categoria.

Non so di un modo per ottenere i primi cinque posti per ciascuna delle categorie in una singola query. Se siete mai andando ad avere solo 45 posti, poi colpendo il database una volta e ottenere i vostri cinque posti per ciascuna categoria è probabilmente l'approccio più efficiente. Colpire il database per tre volte e combinando i risultati non è una brutta cosa, però.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a wordpress.stackexchange
scroll top