Le WordPress d'aujourd'hui, décodé pour les développeurs

Extensions

Un index fulltext MySQL pour une recherche interne sans service externe

Sur un volume modéré de contenu, un index fulltext natif de MySQL évite d'introduire une dépendance à un moteur de recherche tiers.

Par WordPress Développement • 20 décembre 2021 • 4 min de lecture • Aucun commentaire
Un index fulltext MySQL pour une recherche interne sans service externe

2 000 articles, une recherche interne qui ne retourne presque jamais le bon résultat en première position : c’est le symptôme classique de la recherche native de WordPress, qui s’appuie sur une comparaison LIKE sans aucune notion de pertinence. Avant d’introduire un service de recherche tiers, un index fulltext MySQL, natif à la base de données, règle souvent le problème pour un coût d’infrastructure nul.

La recherche par défaut de WordPress compare le terme recherché à une sous-chaîne du titre et du contenu, sans tenir compte de la fréquence du terme, de sa position, ni de la longueur du contenu. Deux articles contenant le même mot une seule fois sont traités à égalité, qu’il apparaisse dans le titre ou noyé dans un paragraphe. Un index fulltext MySQL introduit une véritable notion de pertinence, calculée directement par le moteur de base de données.

Créer l’index fulltext sur les colonnes pertinentes

ALTER TABLE wp_posts
ADD FULLTEXT INDEX idx_recherche_fulltext (post_title, post_content, post_excerpt);

Cet index doit être créé une seule fois, idéalement via une migration versionnée déclenchée par l’extension elle-même plutôt qu’exécutée manuellement, pour qu’elle s’applique aussi sur les environnements de test et de préproduction sans intervention manuelle.

L'essentiel à retenir : Un index FULLTEXT natif couvre une recherche pertinente sans service externe ; MATCH AGAINST dépasse largement la recherche LIKE en pertinence ; La limite pratique se situe autour de quelques dizaines de milliers de contenus

Remplacer la requête de recherche par MATCH AGAINST

Le filtre posts_search permet d’intercepter la clause SQL générée par WP_Query et de la remplacer par une syntaxe MATCH AGAINST, qui exploite l’index fulltext :

function mon_extension_recherche_fulltext( $recherche, $wp_query ) {
    global $wpdb;

    if ( empty( $recherche ) || ! $wp_query->is_search() ) {
        return $recherche;
    }

    $terme = $wpdb->esc_like( get_query_var( 's' ) );

    return $wpdb->prepare(
        " AND MATCH ({$wpdb->posts}.post_title, {$wpdb->posts}.post_content, {$wpdb->posts}.post_excerpt) AGAINST (%s IN NATURAL LANGUAGE MODE) ",
        $terme
    );
}
add_filter( 'posts_search', 'mon_extension_recherche_fulltext', 10, 2 );

Le mode NATURAL LANGUAGE MODE calcule un score de pertinence en interne, utilisé par MySQL pour trier les résultats par défaut selon leur ordre de pertinence, sans intervention supplémentaire côté PHP.

Trier explicitement par score de pertinence

Par défaut, WP_Query trie par date. Pour exploiter réellement le score fulltext, il faut modifier également la clause ORDER BY via le filtre posts_orderby, en recalculant le score de pertinence dans le tri :

function mon_extension_tri_fulltext( $orderby, $wp_query ) {
    global $wpdb;
    if ( empty( get_query_var( 's' ) ) || ! $wp_query->is_search() ) {
        return $orderby;
    }
    $terme = $wpdb->esc_like( get_query_var( 's' ) );
    return $wpdb->prepare(
        "MATCH ({$wpdb->posts}.post_title, {$wpdb->posts}.post_content, {$wpdb->posts}.post_excerpt) AGAINST (%s) DESC",
        $terme
    );
}
add_filter( 'posts_orderby', 'mon_extension_tri_fulltext', 10, 2 );

Les limites de cette approche

  • MySQL ignore par défaut les mots courants trop fréquents (le fameux seuil de fréquence des « mots vides »), ce qui peut surprendre sur certains termes très utilisés dans le contenu.
  • La pertinence reste plus rudimentaire que celle d’un moteur de recherche dédié, qui gère la tolérance aux fautes de frappe et les synonymes.
  • Sur un volume dépassant plusieurs dizaines de milliers de contenus avec une charge de recherche intense, un moteur externe reprend l’avantage en temps de réponse et en fonctionnalités.

Quand cette solution atteint sa limite

Ce constat n’est pas propre à cette technique : au-delà d’un certain volume de contenu et de recherches simultanées, un moteur de recherche externe reste plus adapté, avec ses propres coûts d’infrastructure et de maintenance. La question à se poser reste la même : le volume actuel justifie-t-il réellement cette complexité supplémentaire, ou l’index fulltext natif suffit-il encore largement ?

Un index fulltext ne remplace pas un moteur de recherche dédié — il évite simplement d’en introduire un avant que le besoin ne le justifie réellement.

En résumé

Pour un site de quelques milliers de contenus, un index fulltext MySQL combiné aux filtres posts_search et posts_orderby transforme une recherche native médiocre en une recherche réellement pertinente, sans dépendance à un service tiers ni coût d’infrastructure additionnel. C’est une étape intermédiaire souvent négligée entre la recherche native et un moteur de recherche dédié.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Partager :

À propos de l'auteur

WordPress Développement

Développeur WordPress, passionné par Elementor, le FSE et l’automatisation par IA.

Voir tous ses articles

Dans la même veine

À lire aussi