Indexing
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
Whenever 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:
- when facets are added.
- when facet settings have changed.
- when content is imported programmatically, for example with WP All Import.
- when a category or term’s hierarchy has changed (e.g. changing to a new parent term).
- when a category or term’s custom field content has changed. (Terms can have custom fields added by Advanced Custom Fields or Pods).
- after adding hooks that influence the indexing process.
- after making changes to the registered post types.
- after purging the index table.
- when solving indexing issues.
Other indexing actions
Show indexable post types
Lists 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 a non-searchable post type to be indexed.
Purge the index table
Deletes 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/WordPress 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 getting indexed, check if the exclude_from_search
parameter of the register_post_type() function is set to false
(and re-index afterwards).
The exclude_from_search
query parameter determines whether to exclude posts with this post type from the front-end WordPress search results. FacetWP by default only indexes searchable post types.
You can check which post types FacetWP indexes with the “Show indexable post types” action of the “Re-index” button in FacetWP’s settings.
If you want to index and filter post types that you don’t want in your search results, it is also possible to force FacetWP to index non-searchable post types, with the facetwp_indexer_query_args
hook. See the hook’s usage example.
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 limits 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 periodic re-indexing with WP-Cron
If you do need to schedule a periodic re-index with WP-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' );
}
If you trigger re-indexing with WP-Cron, you may want to disable automatic indexing with the facetwp_indexer_is_enabled hook.
Trigger re-indexing with WP-CLI and server cron
If you prefer the command line, you can also use WP-CLI to manually trigger re-indexing.
Or, if you want to use a cron schedule to control indexing, you can use WP-CLI indexing commands in a server cron job. This can be useful too if you disabled WP-Cron for performance reasons, preventing you from using the above scheduling plugin.
With FacetWP’s built-in WP-CLI indexing command options you can also do partial re-indexes of only specific posts, post types, and facets, and you can purge the index table, as a whole or partially.
Re-indexing with WP-CLI (optimally triggered by a server cron job) is the recommended approach for indexing high-content sites, or sites with large amounts of content imported regularly. In these cases the automatic indexing process can become problematic. Using WP-CLI will give you full control over when the indexing process runs exactly, and at which frequency. In this approach, FacetWP’s automatic indexing can be turned off with the facetwp_indexer_is_enabled hook.
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.
Disable automatic indexing
It is possible to disable automatic (re-)indexing process, with the facetwp_indexer_is_enabled hook:
add_filter( 'facetwp_indexer_is_enabled', '__return_false' );
This can be useful if you are using WP-CLI or WP-Cron to trigger indexing, or if you want to (temporarily) pause automatic indexing when importing content.
It is also possible to disable automatic indexing for certain types of content.
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 );