During a process called indexing, FacetWP analyzes your site and stores facet data into a custom database table for quick lookups.

How to run the indexer

FacetWP indexer buttonsWhenever facets are added or edited, save your changes and then press the Re-index button. This completely rebuilds the index table.

If you press the Stop indexer button while the indexer is running, the index will remain incomplete until the next time you re-index.

While the indexer is running, you can click the rotating icon to see its progress.

It’s recommended to keep the FacetWP settings screen open while the indexer is running.

When to run the indexer

In general, FacetWP will let you know when you need to re-index, by displaying a message in the top right corner of the admin screen after you save facet settings.

Re-indexing is only needed:

Other indexing actions

Show indexable post types

FacetWP Indexing: show indexable post typesLists all post types that will be indexed. If a desired post type is not in the list, make sure that the exclude_from_search parameter of the register_post_type() function is set to false (and re-index afterwards).

Alternatively, you could use the facetwp_indexer_query_args filter to force the post type to be indexed.

Purge the index table

FacetWP Indexing: purge the index tableDeletes and re-creates the facetwp_index database table. This can be helpful in resolving database migration issues or sometimes with other issues like a “The index table is empty” message.

Make sure to re-index again after purging the index table.

Common indexing issues

Solving a stalled indexer

The indexer can stall occasionally: the server ran out of memory, there was a power outage, etc. Fortunately, FacetWP includes built-in resume functionality. It should resume automatically after a minute or two, assuming you keep the FacetWP settings screen open.

If you do notice a stalled indexer, check your web server’s PHP error log for any clues.

If you see a “The index table is empty” message during indexing, click the Re-index button again to re-start the indexer.

If your site is behind a .htpasswd login, the indexer might be blocked from resuming. See the solution below.

If your site is hosted on WP Engine, see the fix below.

Solving issues with indexing post types

When you try to re-index and you get a “The index table is empty” message, or if certain post types are not indexed, check if the exclude_from_search parameter of the register_post_type() function is set to false (and re-index afterwards).

FacetWP only indexes searchable post types by default. You can check which post types FacetWP indexes with the “Show indexable post types” action.

Solving indexing issues for password-protected sites

To bypass PHP timeout issues, FacetWP’s indexer makes a series of HTTP requests to itself. If your site uses HTTP Basic Authentication (.htpasswd), you’ll need to tell FacetWP how to log in.

Add the following into functions.php or into the Custom Hooks add-on:

add_filter( 'http_request_args', function( $args, $url ) {
    if ( 0 === strpos( $url, get_site_url() ) ) {
        $args['headers'] = [
            'Authorization' => 'Basic ' . base64_encode( 'YOUR_USERNAME:YOUR_PASSWORD' )
        ];
    }
    return $args;
}, 10, 2 );

Solving indexing issues with WP Engine

If you are hosting your website on WP Engine and you are experience problems with FacetWP’s indexer stalling or not indexing all your posts, try adding the following line to wp-config.php:

define( 'WPE_GOVERNOR', false );

WP Engine is limiting long queries (longer than 1024 characters) for performance reasons. The above line in wp-config.php prevents that.

How to trigger the indexer programmatically

Use the following code to programmatically do a full re-index:

FWP()->indexer->index();

If you want to re-index a single post instead, set the $post_id parameter:

$post_id = 12345; // must be an integer
FWP()->indexer->index( $post_id );

Trigger re-indexing with WP-CLI

If you prefer the command line, you can also trigger re-indexing by using WP-CLI.

This is a good option if you need to run a large re-index without using the re-index button in wp-admin, as you can use its command options to do partial re-indexes of only the posts, post types, and facets you need. With WP-CLI you can also purge the index table, as a whole or by facet.

Trigger re-indexing with WP All Import

FacetWP doesn’t automatically index content added via the WP All Import plugin.

Fortunately, there are there are hooks that can be used that allow FacetWP to automatically detect and index imported content.

Trigger periodic re-indexing with cron

If you do need to schedule a periodic re-index with cron, you can use the sample plugin below. It runs hourly but you can adjust the schedule as needed:

/*
Plugin Name: FacetWP Schedule Indexer
Plugin URI: https://facetwp.com/
Description: Runs indexer periodically by cron
Version: 1.0
Author: FacetWP, LLC
*/

add_action( 'fwp_scheduled_index', 'fwp_scheduled_index' );
function fwp_scheduled_index() {
  FWP()->indexer->index();
}

register_activation_hook( __FILE__, 'fwp_schedule_indexer_activation' );
function fwp_schedule_indexer_activation() {
  if ( ! wp_next_scheduled( 'fwp_scheduled_index' ) ) {
    wp_schedule_event( time(), 'hourly', 'fwp_scheduled_index' );
  }
}

register_deactivation_hook( __FILE__, 'fwp_schedule_indexer_deactivation' );
function fwp_schedule_indexer_deactivation() {
  wp_clear_scheduled_hook( 'fwp_scheduled_index' );
}

How to index serialized data

With FacetWP, it’s possible to index custom fields stored as a serialized array.

Let’s say you have a facet named days_of_week that uses a custom field with the same name. In the database, an example postmeta row looks like this:

a:2:{i:0;s:6:"Monday";i:1;s:8:"Thursday";}

To index it, add the following code to functions.php, then hit the Re-index button.

<?php

function index_serialized_data( $params, $class ) {
    if ( 'days_of_week' == $params['facet_name'] ) {
        $values = (array) $params['facet_value'];
        foreach ( $values as $val ) {
            $params['facet_value'] = $val;
            $params['facet_display_value'] = $val;
            $class->insert( $params );
        }
        return false; // skip default indexing
    }
    return $params;
}
add_filter( 'facetwp_index_row', 'index_serialized_data', 10, 2 );

See also