Verwenden Sie WP_Query, um mehrere Kategorien mit begrenzten Beiträgen pro Kategorie abzufragen?

wordpress.stackexchange https://wordpress.stackexchange.com/questions/907

  •  16-10-2019
  •  | 
  •  

Frage

Ich habe 3 Kategorien mit jedem 15 Beiträge, ich möchte eine Abfrage an die DB machen, die nur 5 erste Beiträge für jede Kategorie bringt. Wie kann ich das tun?

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

Falls es nicht möglich ist, was ist effizienter, alle Beiträge für die übergeordnete Kategorie zu erhalten und sie durchzuschlingen oder 3 verschiedene Abfragen zu erstellen?

War es hilfreich?

Lösung

Was Sie wollen, ist möglich, müssen Sie sich jedoch eintauchen, in die Sie sich befassen müssen SQL, den ich vermeiden möchte, wann immer möglich (Nicht weil ich es nicht weiß, ich bin ein fortschrittlicher SQL -Entwickler, sondern weil In WordPress möchten Sie die API nach Möglichkeit verwenden Zu den künftigen Kompatibilitätsproblemen im Zusammenhang mit zukünftigen Änderungen der potenziellen Datenbankstruktur zu minimieren.)

SQL mit a UNION Der Bediener ist eine Möglichkeit

SQL zu verwenden, was Sie brauchen, ist a UNION Betreiber in Ihrer Abfrage, so etwas wie diese unter der Annahme, dass Ihre Kategorienschnecken sind "category-1", "category-1" und "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
)

Sie können SQL Union mit a verwenden posts_join Filter

Mit dem oben genannten können Sie entweder Machen Sie den Anruf einfach direkt oder du kannst verwenden ein posts_join Filterhaken wie wie folgt; Beachten Sie, dass ich a benutze PHP Heredoc Seien Sie also sicher, dass die SQL; ist bündig links. Beachten Sie auch, dass ich einen globalen VAR verwendet habe, um die Kategorien außerhalb des Hakens zu definieren, indem Sie die Kategorie -Slugs in einem Array auflisten. Sie können diesen Code in ein Plugin oder in Ihr Thema einfügen functions.php Datei:

<?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 " ;
}

Aber es kann Nebenwirkungen geben

Natürlich mit den Abfragemodifikationshaken wie posts_join lädt immer Nebenwirkungen darin ein, dass sie weltweit an Fragen wirken und daher normalerweise Ihre Modifikationen in einen einwickeln müssen if Das verwendet es nur bei Bedarf und für welche Kriterien können Sie schwierig sein.

Konzentrieren Sie sich stattdessen auf Optimierung?

Ich gehe jedoch davon aus, dass sich Ihre Frage befasst Mehr über die Optimierung als darüber, eine Top 5 -Zeit -3 -Abfrage durchzuführen, oder? Wenn dies der Fall ist, gibt es vielleicht andere Optionen, die die WordPress -API verwenden?

Besser Transienten -API zum Zwischenspeichern verwenden?

Ich gehe davon aus, dass sich Ihre Beiträge nicht so oft ändern, richtig? Was ist, wenn Sie die drei (3) Abfragen regelmäßig annehmen und dann die Ergebnisse mit dem zwischenspeichern Transienten -API? Sie erhalten Wartungscode und großartige Leistung. ein gutes bisschen besser als das UNION Abfrage oben, weil WordPress die Beiträge als serialisiertes Array in einem Datensatz der Beiträge speichert wp_options Tisch.

Sie können das folgende Beispiel nehmen und in die Root Ihrer Website fallen test.php Um dies zu testen:

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

Zusammenfassung

Während ja, Sie können das tun, was Sie für eine SQL gebeten haben, UNION Abfrage und die posts_join Filterhaken Sie sind wahrscheinlich besser mit dem Caching mit dem anbieten Transienten -API stattdessen.

Hoffe das hilft?

Andere Tipps

WP_Query() unterstützt nicht so etwas wie Erst x für jede Katze. Anstatt von WP_Query() Sie können verwenden get_posts() In jeder Ihrer Kategorien, sagen Sie also dreimal:

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

$posts Enthält nun die ersten fünf Beiträge für jede Kategorie.

Ich weiß keinen Weg, um die ersten fünf Beiträge für jede der Kategorien in einer einzelnen Abfrage zu erhalten. Wenn Sie jemals nur 45 Beiträge haben, dann ist es wahrscheinlich der effizienteste Ansatz, die Datenbank auf die Datenbank zu drücken und Ihre fünf Beiträge für jede Kategorie zu erhalten. Dreimal auf die Datenbank zu schlagen und die Ergebnisse zu kombinieren, ist jedoch keine schlechte Sache.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit wordpress.stackexchange
scroll top