Somehow my post counts are incorrect due to inserting rows via php. I have the following code to update the count, is it correct?

global $wpdb;
$result = mysql_query("SELECT term_id,term_taxonomy_id FROM $wpdb->term_taxonomy where taxonomy = 'category'");
while ($row = mysql_fetch_array($result)) {
  $term_taxonomy_id = $row['term_taxonomy_id'];      
  $countresult = mysql_query("SELECT object_id FROM $wpdb->term_relationships WHERE object_id IN (SELECT ID FROM $wpdb->posts WHERE post_type = 'post' AND post_status = 'publish') AND term_taxonomy_id = '$term_taxonomy_id'");
  $count = mysql_num_rows($countresult);
  mysql_query("UPDATE $wpdb->term_taxonomy SET count = '$count' WHERE term_taxonomy_id = '$term_taxonomy_id'");

If you just want to update the counts of posts in each term, wp_update_term_count_now( $terms, $taxonomy ) should do it... just pass the terms affected as an array and run it once for each taxonomy you have.

You can also call wp_defer_term_counting( true ) before inserting new rows, and then after adding your posts, catch up on the counts by calling wp_defer_term_counting( false ).

  • ok I see wp_update_term_count_now does pretty much the same thing.. will it handle thousands of categories I wonder? and what about post status - does this not affect the count? only published posts should be counted - these functions dont include that - Ive editted my 'query'.
    – Innate
    Mar 3 '11 at 12:34
  • Well, the core function does loop through each of the terms you pass it, so you probably shouldn't pass an arbitrarily large array of terms or else you risk running out of memory. Its not storing anything large in it, though, so it should be able to handle thousands of terms at a time. It does look like the default count callback includes any posts and not just published ones, but you can override that by defining a function - like your SQL above - that you register along with the taxonomy as your update_count_callback. Mar 3 '11 at 16:48
  • Quick question, what happens if I leave the update_count_callback empty (default)?? Will it count the post type that the taxonomy is including drafts, etc?
    – trusktr
    Jun 29 '11 at 2:40
  • 1
    @trusktr - Sounds like you're asking a completely different question... but yes. The default update count callback function includes all posts of any status (draft, pending, etc). If you want to register your own to filter out unpublished posts, you would register that function at the same time you register the taxonomy. Jun 29 '11 at 16:57
  • Cool, thanks! That's what I inferred from reading this question, but now know for sure.
    – trusktr
    Jul 1 '11 at 6:29

There's a sql script written by someone else that does the job - updates counts for product categories in woocommerce or any other category counts.

Only takes a few seconds to run as well:



Example for the answer of goldenapples:

$update_taxonomy = 'my_taxonomy';
$get_terms_args = array(
        'taxonomy' => $update_taxonomy,
        'fields' => 'ids',
        'hide_empty' => false,

$update_terms = get_terms($get_terms_args);
wp_update_term_count_now($update_terms, $update_taxonomy);

In my opinion the best way to do this is by using WP-CLI. There's a command for that:

$ wp term recount category

Find the documentation here: https://developer.wordpress.org/cli/commands/term/recount/

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.