Query posten verschiedene Autoren

Ich versuche Post aus einer zufällig bestellten Kategorie zu bekommen, stelle aber sicher, dass der Autor sich nicht wiederholt.

Also habe ich diese Abfrage, die wie beabsichtigt funktioniert, aber es gibt die Chance, dass der Autor in diesen 4 Posts wiederholt wird. Also irgendwelche Ideen wie ich dafür sorgen könnte, dass es nicht geht?

Ich dachte daran, $ wpdb zu verwenden, aber ich hoffte auf eine einfachere Lösung.

$args = array ( 'post_type' => 'post', 'post_status' => 'publish', 'category_name' => 'premium', 'orderby' => 'rand', 'posts_per_page' => 4, 'post__not_in' => get_option( 'sticky_posts' ), 'date_query' => array( array( array( 'before' => 'this week' ) ), ), ); $query = new WP_Query( $args ); 

bearbeiten:

Ich habe das in der Schleife versucht. Aber aus irgendeinem Grund wird nur ein Post get angezeigt und das $ temp-Array wird immer noch mit allen Duplikaten gefüllt.

 $temp=array(); if ($query->have_posts()) : while ($query->have_posts()) : $query->the_post(); $author_id = the_author_meta( 'ID' ); if( !in_array($author_id, $temp) ): array_push($temp, $author_id); //loop stuff endif; endwhile;endif;wp_reset_query(); 

Solutions Collecting From Web of "Query posten verschiedene Autoren"

Mit dem, was Sie fragen, ist es wirklich schwierig, einen performanten einfachen Weg zu finden, der auch zuverlässig ist. Wie @birgire bereits sagte, ist seine Lösung nicht zuverlässig, aber aus Tests scheint es die schnellste Taktung bei 2 db Abfragen in etwa 0,015s durchschnittlich zu sein.

Nach einer kurzen Diskussion zwischen @birgire und mir in Kommentaren zu seiner Antwort habe ich beschlossen, es mit dem zu versuchen, was WordPress anbietet. Es ist der zuverlässigste Weg bei weitem, aber es hat einen Preis, bei 20 db Abfragen in etwa 0,05 Mittel.

Das wirklich große Problem ist, dass Sie aufgrund der Anfrage nach zufälligen Ergebnissen keinen Cache verwenden können, also musste ich nach anderen Wegen suchen, um Zeit und DB-Aufrufe zu reduzieren.

Für den ersten Abschnitt habe ich diese Lösung von @birgire verwendet (auch von ihm in Kommentaren erwähnt), wo wir pre_user_query , um die SQL-Abfrage von WP_User_Query zu WP_User_Query , um nur die Anzahl der Autoren zu erhalten, die nach dem Zufallsprinzip benötigt werden. Dieser Abschnitt des Codes ist sehr schnell. Um die performance zu erhöhen, habe ich WP_User_Query , dass nur die Autoren-IDs WP_User_Query , da dies alles ist, was wir brauchen. Dieser Abschnitt Uhr in 2 db Abfragen in 0,002s durchschnittlich.

Um einen einzelnen Beitrag von jedem Autor zu erhalten, müssen wir für jeden einen einzelnen WP_Query , der in Ihrem Fall insgesamt 4 WP_Query . Dies ist die ziemlich teure Seite der function. Faktoren, die die Abfragen wirklich verlangsamen, sind die Tatsache, dass wir eine zufällige Reihenfolge benötigen, und wir machen auch eine tax_query die Join-Klauseln verwendet.

Der einzige Weg, wie ich diesen Abschnitt beschleunigen konnte, war, auch nur die Post-IDs zu bekommen. Alles in allem kam dies schneller, als die kompletten Posts zu bekommen und sie anzuzeigen, als nur die Post-IDs zu nehmen und danach eine weitere WP_Query . Ich habe 7 Abfragen weniger eine zusätzliche Instanz von WP_Query

OK, genug reden, hier ist die function: ( Kann vielleicht etwas Feinabstimmung verwenden )

 function wpse177162_random_author_posts($number = 4, $args = []) { function my_pre_user_query( $q ) { $limit = preg_replace( '/[^\d]/', '', $q->query_limit ); $from = 'WHERE 1=1'; $to = sprintf( 'WHERE RAND()< (SELECT ((%d/COUNT(*))*10) FROM %susers)', $limit, $GLOBALS['wpdb']->prefix ); $q->query_where = str_replace( $from, $to, $q->query_where ); $q->query_orderby = ' ORDER BY RAND() '; // remove the hook remove_action( current_filter() , __FUNCTION__ ); } $user_query_args = [ 'who' => 'authors', 'fields' => 'ID', 'number' => $number, ]; add_action( 'pre_user_query', 'my_pre_user_query' ); $user_query = new WP_User_Query($user_query_args); remove_action( 'pre_user_query', 'my_pre_user_query' ); $users = $user_query->results; $post_ids = ''; if ($users) { foreach ($users as $user) { $user_args = [ 'author' => $user, 'fields' => 'ids', 'no_found_rows' => true ]; $combined_args = wp_parse_args($args, $user_args); $q = new WP_Query($combined_args); $q_posts[] = $q->posts; } foreach ($q_posts as $q_post) { foreach ($q_post as $v ) { $post_ids[] = $v; } } } return (array) $post_ids; } 

Nur ein paar Anmerkungen zur function

  • Der erste Parameter $number ist die Anzahl der zu erhaltenden Autoren

  • Der zweite Parameter ist $args den von WP_Query verwendeten WP_Query und wird auch direkt als Abfrageargument in WP_Query . Sie können dies auf die gleiche Weise verwenden, mit einer Ausnahme, setzen Sie nicht die Autor Parameter, dies wird die function zu brechen

Um zu sehen, wie es verwendet wird, würden Sie es dann in Ihrer Vorlage verwenden

 $author_posts = wpse177162_random_author_posts(4, array('posts_per_page' => 1, 'cat' => 1, 'orderby' => 'rand')); $q = new WP_Query(array('post__in' => $author_posts)); 

Wie bereits erwähnt, liegt der Grund für die zusätzliche WP_Query in der performance, da es auf diese Weise zu besseren WP_Query beim Testen führt

BEARBEITEN

Auf Empfehlung von @birgire habe ich den obigen Code mit no_found_rows aktualisiert, um db-Aufrufe zu speichern. Ich habe eine leichte performancesverbesserung bekommen, beim Test habe ich 4 db Calls gespeichert, obwohl die Zeit im Grunde gleich geblieben ist.

update_post_meta_cache und update_post_term_cache verdoppelten tatsächlich die Zeit, die zum update_post_term_cache der Abfragen benötigt wurde, und die Abfragen blieben durchgehend bei 20. Also kein Weg zu gehen 🙂

Aus Neugierde habe ich mit statischen SQL-Abfragen herumgespielt und dieser schien zu funktionieren:

 SELECT r.post_author, r.ID, r.post_title FROM ( SELECT p.post_author, p.ID, p.post_title FROM wp_posts p INNER JOIN wp_term_relationships tr ON ( p.ID = tr.object_id ) WHERE p.post_date < '2015-02-05 00:00:00' AND p.ID NOT IN (10,20) AND tr.term_taxonomy_id IN (1) AND p.post_type = 'post' AND p.post_status = 'publish' ORDER BY RAND() ) as r GROUP BY r.post_author LIMIT 0,4 

Zuerst probierte ich eine direkte Gruppe nach dem Feld post_author und post_author nach RAND() aber dann spielten die nicht aggregierten Felder nicht mit.

Aber das ist natürlich nicht sehr flexibel 😉

Eine andere Lösung, die funktioniert, wird erklärt: hier

Hinzufügen des Filters vor der Abfrage:

 function filter_authors($groupby) { global $wpdb; $groupby = " {$wpdb->posts}.post_author"; return $groupby; } add_filter('posts_groupby','filter_authors'); 

Und nicht vergessen, es danach zu entfernen:

 remove_filter('posts_groupby','filter_authors'); 

Diese Lösung scheint ziemlich gut zu funktionieren.