Why Init Review System Uses 3 Meta Keys for Storing Ratings

In post rating systems on WordPress, the way you store rating data plays a crucial role in performance and scalability. The Init Review System plugin chooses to store three separate meta fields per post: total score, number of votes, and average score. This article explains the technical reasoning behind this design and provides practical WP_Query examples to filter and sort posts based on rating data.

Why Init Review System Uses 3 Meta Keys for Storing Ratings

In the Init Review System plugin, each user-submitted rating is stored using three separate meta keys for each post:

  • _init_review_total: the total score accumulated from all votes
  • _init_review_count: the number of valid votes
  • _init_review_avg: the average score (rounded to 2 decimal places)

While this approach may seem redundant (since the average can be recalculated at any time), it brings three key advantages:

1. Better query performance

If we don’t store _init_review_avg directly, WordPress would need to fetch both _init_review_total and _init_review_count, then calculate the average in PHP. This makes it impossible to sort posts by average score using orderby in SQL. By saving the average score as a separate meta key, we allow WP_Query to sort results efficiently at the database level.

2. Separation of logic and presentation

Every time a new vote is submitted, the plugin updates all three values at once. This ensures that frontend rendering doesn’t have to compute the average repeatedly, which reduces processing overhead and rounding inconsistencies. It also improves compatibility with object caching and REST API caching.

3. Flexible filtering conditions

Storing all three values enables a wide range of queries — such as finding posts with at least 10 votes or with an average rating above 4.5. These are common requirements for building review listings, top charts, or content rankings.

Practical WP_Query Examples

Get posts with an average rating of 4.5 or higher

new WP_Query([
  'post_type'  => 'post',
  'meta_query' => [
    [
      'key'     => '_init_review_avg',
      'value'   => 4.5,
      'type'    => 'NUMERIC',
      'compare' => '>=',
    ]
  ]
]);

Get posts with at least 20 votes

new WP_Query([
  'post_type'  => 'post',
  'meta_query' => [
    [
      'key'     => '_init_review_count',
      'value'   => 20,
      'type'    => 'NUMERIC',
      'compare' => '>=',
    ]
  ]
]);

Order posts by highest average rating

new WP_Query([
  'post_type'  => 'post',
  'meta_key'   => '_init_review_avg',
  'orderby'    => 'meta_value_num',
  'order'      => 'DESC',
]);

Order posts by most total votes

new WP_Query([
  'post_type'  => 'post',
  'meta_key'   => '_init_review_count',
  'orderby'    => 'meta_value_num',
  'order'      => 'DESC',
]);

Get posts with average score ≥ 4.5 and at least 50 votes

new WP_Query([
  'post_type'  => 'post',
  'meta_query' => [
    'relation' => 'AND',
    [
      'key'     => '_init_review_avg',
      'value'   => 4.5,
      'type'    => 'NUMERIC',
      'compare' => '>=',
    ],
    [
      'key'     => '_init_review_count',
      'value'   => 50,
      'type'    => 'NUMERIC',
      'compare' => '>=',
    ]
  ],
  'orderby' => 'meta_value_num',
  'meta_key' => '_init_review_avg',
  'order'   => 'DESC',
]);

Conclusion

Storing _init_review_total, _init_review_count, and _init_review_avg independently gives the Init Review System plugin the best of both worlds: fast database queries and flexible rating logic. This design is practical, optimized, and production-ready for modern WordPress review systems.

Comments


  • No comments yet.

Init Toolbox

Press Ctrl + \ on desktop, or swipe left anywhere on mobile.

Login