When importing products with the WP All Import plugin (or the free version) , FacetWP’s automatic indexer is triggered. This happens because posts and/or terms are being inserted and/or saved during the import process. Normally this is a good thing, but because importing happens at a very high frequency, this can lead to several issues:

Indexing and server issues during importing

FacetWP’s automatic indexer running during the import process is not optimal. We’ve seen the following issues happening:

  • 500 fatal errors.
  • 502 errors caused by the server not being able to handle all necessary processing. This issue can specifically happen in multi-lingual setups with WPML, WPML All Import, and FacetWP’s Multilingual add-on installed.
  • (Child) terms not being added to imported posts for non-default languages, in multi-lingual setups with WPML and FacetWP’s Multilingual add-on installed. If this happens depends happens depending on the language of the imported posts and the language used on the import admin page.

To prevent these issues, two things need to be done:

  1. FacetWP’s indexer needs to be prevented from running during the import process.
  2. The indexer needs to be triggered to run after the import process has finished.

1. Prevent re-indexing during importing

The 'Increase import speed by disabling do_action calls in wp_insert_post during import' setting.
The “Increase import speed by disabling do_action calls in wp_insert_post during import” setting.

To prevent the above issues, FacetWP’s automatic indexer needs to be prevented from running during the import process.

There are three ways to do this:

You could enable the “Increase speed by disabling do_action calls in wp_insert_post during import” setting (found in All Import › Manage Imports › Settings › Configure Advanced Settings). However, this setting disables all action hooks from all plugins (not only FacetWP’s) and may have undesired consequences.

Disable automatic indexing.
Disable automatic indexing.

A better way to do this manually is to temporarily disable FacetWP’s “Enable automatic indexing” setting (introduced in version 4.3.4) during the import. Make sure to re-enable it when the import has finished.

To automatically stop FacetWP’s indexer from running during the import process, add the following snippet to your (child) theme’s functions.php.

The code works in the free and Pro version, when doing manual imports, cron imports, scheduled imports, WP-Cli imports, and when uploading import files. Note that it needs FacetWP v4.3.4+ to function correctly.

How to use custom PHP code?

PHP code can be added to your (child) theme's functions.php file. Alternatively, you can use the Custom Hooks add-on, or a code snippets plugin. More info

// Disable FacetWP indexer during manual and cron importing by WP All Import // Needs FacetWP v4.3.4+ add_filter( 'facetwp_indexer_is_enabled', function( $enabled ) { // WP All Import get import id function facetwp_wp_all_import_get_import_id() { global $argv; $import_id = 'new'; if ( ! empty( $argv ) ) { // First check for the ID set by the WP_CLI code. $temp_id = apply_filters( 'wp_all_import_cli_import_id', false ); if ( $temp_id !== false && is_numeric( $temp_id ) ) { $import_id = $temp_id; } else { // Try to get the ID from the CLI arguments if it's not found otherwise. $import_id_arr = array_filter( $argv, function( $a ) { return ( is_numeric( $a ) ) ? true : false; } ); if ( ! empty( $import_id_arr ) ) { $import_id = reset( $import_id_arr ); } } } if ( $import_id == 'new' ) { if ( isset( $_GET['import_id'] ) ) { $import_id = $_GET['import_id']; } elseif ( isset( $_GET['id'] ) ) { $import_id = $_GET['id']; } } return $import_id; } // WP All Import detect importing function wpai_check_is_import_running() { // Manually running an import $manual_run = isset( $_GET['page'] ) && ( $_GET['page'] == 'pmxi-admin-import' || $_GET['page'] == 'pmxi-admin-manage' ); // Cron jobs running an import $cron_run = isset( $_GET['import_id'] ) && isset( $_GET['action'] ) && $_GET['action'] == 'processing'; // Automatic Scheduling service running an import $automatic_scheduling_run = ( isset( $_GET['action'] ) && $_GET['action'] == 'wpai_public_api' ) && ( isset( $_GET['q'] ) && $_GET['q'] == 'scheduling/process' ); // Manually uploading an import file $manual_upload = ( isset( $_GET['page'] ) && $_GET['page'] == 'pmxi-admin-settings' ) && ( isset( $_GET['action'] ) && $_GET['action'] == 'upload' ); // Extra check: see if import ID is numeric $import_id = is_numeric( facetwp_wp_all_import_get_import_id() ); // Check if they're importing if ( $manual_run || $cron_run || $automatic_scheduling_run || $manual_upload || $import_id ) { return true; } else { return false; } } // Disable indexer during WP All Import importing if ( defined( 'PMXI_VERSION' ) ) { if ( wpai_check_is_import_running() ) { return false; } } return $enabled; }, 5 );

2. Trigger re-indexing after a finished import

To re-index after the import has finished, you could just click the Re-index button. But if you run regular or scheduled imports, you may want to automate this with one of the two hooks described below.

These two hooks work when doing manual imports, cron imports, scheduled imports, and WP-Cli imports. They work in both the free and the pro versions of WP All Import.

Trigger re-indexing of individual posts

To re-index each individual post separately after it has been imported, add the following code to your (child) theme’s functions.php:

How to use custom PHP code?

PHP code can be added to your (child) theme's functions.php file. Alternatively, you can use the Custom Hooks add-on, or a code snippets plugin. More info

// Re-index each post after it has been imported function facetwp_reindex_post( $post_id ) { if ( function_exists( 'FWP' ) ) { FWP()->indexer->index( $post_id ); // Re-index the currently saved post } } add_action( 'pmxi_saved_post', 'facetwp_reindex_post' );

Trigger a full re-index after an import

If you are importing large datasets it is more efficient to re-index the entire site after an import. To do this, use the following snippet instead:

How to use custom PHP code?

PHP code can be added to your (child) theme's functions.php file. Alternatively, you can use the Custom Hooks add-on, or a code snippets plugin. More info

// Run a full re-index of all posts after the import has finished function facetwp_reindex_all_posts( $import_id ) { if ( function_exists( 'FWP' ) ) { FWP()->indexer->index(); // Run a full re-index of all posts } } add_action( 'pmxi_after_xml_import', 'facetwp_reindex_all_posts' );

Alternative: trigger re-indexing after importing with WP-Cron

Alternatively, you could automatically trigger the indexer with a one-time WP-Cron event, after importing has finished.

Compared to the above approach, the advantage would be that the indexing process runs in a separate process from the importing process, preventing any (server) issues caused by running the two processes at the same time, in direct succession.

The disadvantage would be that this solution uses WP-Cron, which is only triggered when there is front-end activity. Which means it can take time for the re-indexing to start. So if you don’t see it running, visit a front-end page. To check on cron activity, you can use the WP Crontrol plugin.

To schedule a one-time WP-Cron event that starts a full re-index after an import has finished, add the following to your (child) theme’s functions.php:

How to use custom PHP code?

PHP code can be added to your (child) theme's functions.php file. Alternatively, you can use the Custom Hooks add-on, or a code snippets plugin. More info

function fwp_all_index() { FWP()->indexer->index(); } add_action( 'fwp_all_index', 'fwp_all_index' ); function facetwp_reindex_all_posts( $import_id ) { wp_schedule_single_event( time(), 'fwp_all_index'); } // Trigger a one-time cron event to start the indexer after an import add_action( 'pmxi_after_xml_import', 'facetwp_reindex_all_posts' );

Prevent duplicate results with imported posts

If you are regularly importing posts, be aware of the fact that imported posts often end up having the exact same post date.

This can lead to issues when queries are using the post date in their orderby query argument. Adding to the problem is that WordPress by default will order queries by post date.

In this scenario with multiple posts sharing the same date, if no specific order is set for a query, or if it is intentionally set to date, MySQL will not have a fallback and will often sort erratically. This can lead to duplicate results in your listing, most visibly when you are using a Pager/Load more facet or a Sort facet.

The problem can be easily fixed by setting something else than date in the orderby argument of your queries. Or by introducing a secondary, fallback sorting method.

See also

Last updated: November 25, 2024