Ich habe einen benutzerdefinierten Beitragstyp namens entries
, der Teilnehmer für einen Wettbewerb enthält. Es gibt eine 5-Sterne-Bewertungsfunktion, die Bewertungen werden mit der entries
gespeichert. So kann ich den ratings_average
, ratings_count
und ratings_sum
mit einem WP_Query
erhalten:
$args = array(
'post_type' => 'entry',
'orderby' => 'ratings_average',
'order' => 'DESC',
'posts_per_page' => 10,
'post_status' => 'publish'
);
$loop = new WP_Query($args);
Jetzt muss ich den Bayesianischen Durchschnitt oder Mittelwert oder die Schätzung (die nur verschiedene Namen für dasselbe sind, soweit ich das beurteilen kann) berechnen, die mit dieser SQL-Abfrage möglich sein sollten:
SELECT
( SELECT COUNT(*) FROM `bayesian_test` ) AS total_entrants,
( SELECT SUM( vote_count ) FROM `bayesian_test` ) AS total_votes,
( (SELECT total_votes) / (SELECT total_entrants) ) AS average_votes,
( SELECT SUM( rating_count ) FROM `bayesian_test` ) AS total_ratings,
( (SELECT total_ratings) / (SELECT total_entrants) ) AS average_rating,
post_title,
( ( (SELECT average_votes) * (SELECT average_rating) ) + (vote_count * rating_average) ) / ( (SELECT average_votes) + vote_count) AS mean
FROM
bayesian_test
ORDER BY
mean ASC;
Gibt es eine Möglichkeit, SQL-Anweisungen mit WP_Query
zu kombinieren?
Oder wie kann ich am besten die gleichen Ergebnisse erzielen, die ich mit WP_Query
in einer SQL-Abfrage erhalte, mit der ich in $wpdb
arbeiten kann?
Die entries
werden von WordPress im wp_posts
mit post_type
entry
gespeichert und der ratings_count
, ratings_sum
und ratings_average
werden im wp_postmeta
gespeichert. Also müsste ich einen Join schreiben, um diese zu erhalten, und dann die obige Abfrage für das Ergebnis durchführen. Wäre das nicht schwer für die DB? Dies wird in einem Dashboard-Widget angezeigt, sodass die Abfrage jedes Mal ausgeführt wird, wenn jemand /wp-admin/
drückt.
Was ist der beste (wie auch der effizienteste) Weg, um dies in Angriff zu nehmen?
Das Bayesian Rating/der Durchschnitt wird wie folgt berechnet: http://fulmicoton.com/posts/bayesian_rating/
Dies ist der (aktualisierte) Code, den ich verwende und der die erwarteten Ergebnisse liefert:
$args = array(
'post_type' => 'entry',
'orderby' => 'bayesian_average',
'order' => 'DESC',
'post_status' => 'publish'
);
$loop = new WP_Query($args);
$number_of_entrants = $loop->post_count;
$total_ratings = $total_num_votes = 0;
foreach ($loop->posts as $query_post) {
$count = $query_post->ratings_count;
$average = $query_post->ratings_average;
$total_num_votes += $count;
$total_ratings += $average;
}
$average_rating = $total_ratings / $number_of_entrants;
$avg_num_votes = $total_num_votes / $number_of_entrants;
if ($loop>have_posts()):
?>
<table class="wp-list-table widefat fixed striped pages">
<thead>
<tr>
<th scope="col" id="entry"><?php _e('Entry', 'textdomain'); ?></th>
<th scope="col" id="rating-average"><?php _e('Rating average', 'textdomain'); ?></th>
<th scope="col" id="rating-count"><?php _e('Rating count', 'textdomain'); ?></th>
<th scope="col" id="beyesian-rating"><?php _e('Bayesian Rating', 'textdomain'); ?></th>
</tr>
</thead>
<tbody><?php
global $post;
while ($loop->have_posts()) :
$loop->the_post();
$title = get_the_title();
$this_num_votes = $post->ratings_count;
$this_avg_rating = $post->ratings_average;
$bayesian_average = (($avg_num_votes * $average_rating) + ($this_num_votes * $this_avg_rating)) / ($avg_num_votes + $this_num_votes);
update_post_meta(get_the_ID(), 'bayesian_average', $bayesian_average); ?>
<tr>
<td><a href="<?php echo get_permalink(); ?>" target="_blank"
title="<?php echo $title; ?>"><?php echo $title; ?>
</a></td>
<td>
<?php echo $post->ratings_average; ?>
</td>
<td>
<?php echo $post->ratings_count; ?>
</td>
<td>
<?php echo round($bayesian_average, 3); ?>
</td>
</tr><?php
endwhile; ?>
</tbody>
</table><?php
else:
_e('No Entries', 'textdomain');
endif;