# wp-cli et Algolia : réindexer 100 000 contenus sans bloquer l’admin

> Une commande WP-CLI qui traite la réindexation Algolia par lots, avec reprise en cas d'interruption, pour un catalogue de cent mille contenus.

- Auteur : WordPress Développement
- Publié le : 2022-08-26
- Mis à jour le : 2022-08-26
- Catégorie : Outils &amp; workflow
- URL : https://www.wpmoderne.fr/outils/wp-cli-algolia-reindexer-100000-contenus/

## L’essentiel

- Traiter la réindexation par lots plutôt qu'en une seule requête
- Reprendre exactement où l'interruption a eu lieu
- Séparer l'indexation de la navigation dans l'admin

7 h 40 du matin : c'est le créneau choisi pour lancer, pour la première fois, une réindexation complète d'un catalogue de cent mille fiches produits vers Algolia, avant l'ouverture des bureaux et avant le pic de trafic habituel du site. Une précédente tentative, lancée en pleine journée avec le plugin d'indexation par défaut, avait ralenti l'ensemble de l'administration WordPress au point de la rendre inutilisable pendant près d'une heure.

Le problème ne venait pas d'Algolia lui-même, dont l'API encaisse sans difficulté ce volume, mais de la façon dont l'extension standard construisait sa file d'indexation : une requête unique tentant de charger l'ensemble des contenus en mémoire avant de les envoyer par petits paquets, saturant la mémoire PHP allouée au processus.

## Concevoir une commande WP-CLI dédiée

Plutôt que de dépendre de l'interface d'administration pour déclencher la réindexation, nous avons écrit une commande personnalisée qui traite le catalogue par lots, avec un curseur de reprise stocké entre chaque exécution :

```
WP_CLI::add_command( 'algolia reindex-catalogue', function( $args, $assoc_args ) {
    $taille_lot = (int) ( $assoc_args['batch-size'] ?? 200 );
    $dernier_id = (int) get_option( 'algolia_reindex_curseur', 0 );

    do {
        $produits = get_posts( [
            'post_type'      => 'produit',
            'posts_per_page' => $taille_lot,
            'post__not_in'   => [],
            'orderby'        => 'ID',
            'order'          => 'ASC',
            'fields'         => 'ids',
            'meta_query'     => [
                [ 'key' => '_id_interne', 'value' => $dernier_id, 'compare' => '>', 'type' => 'NUMERIC' ],
            ],
        ] );

        if ( empty( $produits ) ) {
            break;
        }

        envoyer_lot_vers_algolia( $produits );
        $dernier_id = end( $produits );
        update_option( 'algolia_reindex_curseur', $dernier_id );

        WP_CLI::log( "Lot traité jusqu'à l'ID {$dernier_id}" );
    } while ( true );

    delete_option( 'algolia_reindex_curseur' );
    WP_CLI::success( 'Réindexation complète terminée.' );
} );
```

> L'essentiel à retenir : Traiter la réindexation par lots plutôt qu'en une seule requête ; Reprendre exactement où l'interruption a eu lieu ; Séparer l'indexation de la navigation dans l'admin

## Pourquoi un curseur plutôt qu'une pagination classique

Une pagination classique par numéro de page pose un problème dès que des contenus sont ajoutés ou supprimés pendant le traitement : les pages se décalent, et certains contenus finissent traités deux fois, d'autres jamais. Le curseur basé sur l'identifiant interne du dernier contenu traité évite ce décalage, quelle que soit l'activité du site pendant la réindexation.

## Reprendre après une interruption

Le curseur est enregistré en base après chaque lot traité avec succès, ce qui permet de relancer exactement la même commande après une interruption — coupure réseau, redémarrage du serveur, arrêt volontaire — sans retraiter les lots déjà envoyés :

```
wp algolia reindex-catalogue --batch-size=200
# Interruption après 40 000 contenus...
wp algolia reindex-catalogue --batch-size=200
# Reprend automatiquement à partir de l'ID 40 001
```

## Limiter l'impact sur l'administration

Deux réglages supplémentaires ont permis d'éviter tout ralentissement perceptible de l'admin pendant l'opération :

- Une pause courte entre chaque lot (`sleep(1)`), pour laisser respirer le serveur entre deux envois, plutôt qu'un enchaînement continu.
- Une exécution via `wp cli cmd` lancée depuis une tâche cron système plutôt que depuis `wp-cron`, pour ne pas dépendre du trafic entrant du site pour déclencher chaque étape.

## Résultat mesuré

La réindexation complète des cent mille fiches produits s'est achevée en un peu moins de quarante minutes, exécutée en dehors des heures de bureau, sans qu'aucun utilisateur de l'administration n'ait signalé de ralentissement — contrairement à la première tentative qui avait nécessité une intervention manuelle en urgence.

> Traiter un gros volume par petits lots avec un point de reprise coûte quelques lignes de code de plus, mais évite de tout rejouer après le moindre incident.

## En résumé

Réindexer cent mille contenus vers Algolia n'exige pas une infrastructure particulière, mais une commande conçue pour reprendre exactement où elle s'est arrêtée, plutôt qu'un traitement monolithique qui échoue tout ou rien. Cette discipline de conception se retrouve utile bien au-delà d'Algolia, pour tout traitement de masse sur un catalogue volumineux.
