# Recherche vectorielle dans MariaDB pour un site WordPress

> Stocker et interroger des embeddings directement dans MariaDB grâce au type VECTOR, sans dépendre d'un service tiers pour la recherche sémantique.

- Auteur : Clément Hadrot
- Publié le : 2025-09-12
- Mis à jour le : 2025-09-12
- Catégorie : IA &amp; MCP
- URL : https://wpmoderne.dev.wordpress-developpement.fr/ia-mcp/recherche-vectorielle-mariadb-wordpress/

## L’essentiel

- Le type VECTOR de MariaDB stocke les embeddings comme une colonne native
- Un index HNSW accélère la recherche par similarité
- Tout reste dans l'infrastructure existante, sans service externe

La recherche sémantique repose sur des embeddings, ces vecteurs numériques qui représentent le sens d'un texte, comparés ensuite par proximité pour trouver du contenu similaire. Jusqu'ici, la plupart des tutoriels que nous avions vus s'appuyaient sur un service externe dédié pour stocker et interroger ces vecteurs. Avec l'arrivée du type `VECTOR` dans MariaDB, la base de données déjà utilisée par la plupart des installations WordPress peut désormais assumer ce rôle directement. Nous ne reprenons pas ici l'introduction aux embeddings eux-mêmes, déjà traitée ailleurs : ce texte se concentre sur l'intégration MariaDB.

Voici comment nous avons mis en place cette recherche sur un site de documentation technique volumineux, sans ajouter le moindre service externe à l'infrastructure existante.

## Créer la colonne vectorielle

MariaDB stocke un vecteur dans une colonne de type `VECTOR`, avec une dimension fixe correspondant à celle du modèle d'embedding utilisé. Nous avons choisi un modèle produisant des vecteurs à 1536 dimensions, la colonne est donc déclarée en conséquence dans une table dédiée liée aux articles.

```
CREATE TABLE wp_articles_embeddings (
    id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
    post_id BIGINT UNSIGNED NOT NULL,
    embedding VECTOR(1536) NOT NULL,
    PRIMARY KEY (id),
    UNIQUE KEY post_id (post_id),
    VECTOR INDEX (embedding)
) ENGINE=InnoDB;
```

## Générer et insérer les embeddings depuis WordPress

À chaque publication ou mise à jour d'un article, un hook déclenche l'appel au modèle d'embedding, puis insère le vecteur obtenu dans la table dédiée via `$wpdb`. MariaDB attend le vecteur sous une forme binaire précise, produite par la fonction `VEC_FromText` à partir d'une chaîne JSON.

```
add_action( 'save_post', function ( $post_id ) {
    global $wpdb;
    if ( wp_is_post_revision( $post_id ) || 'publish' !== get_post_status( $post_id ) ) {
        return;
    }
    $texte     = wp_strip_all_tags( get_post_field( 'post_content', $post_id ) );
    $embedding = generer_embedding_via_api( $texte ); // tableau de 1536 flottants
    $json      = wp_json_encode( $embedding );

    $wpdb->query( $wpdb->prepare(
        "INSERT INTO {$wpdb->prefix}articles_embeddings (post_id, embedding)
         VALUES (%d, VEC_FromText(%s))
         ON DUPLICATE KEY UPDATE embedding = VEC_FromText(%s)",
        $post_id, $json, $json
    ) );
} );
```

> L'essentiel à retenir : Le type VECTOR de MariaDB stocke les embeddings comme une colonne native ; Un index HNSW accélère la recherche par similarité ; Tout reste dans l'infrastructure existante, sans service externe

## Interroger par similarité

La recherche s'appuie sur la fonction de distance disponible avec l'index vectoriel, qui trie les résultats par proximité avec le vecteur de la requête, calculé à la volée à partir du texte tapé par l'utilisateur. L'index de type HNSW créé sur la colonne accélère considérablement cette opération par rapport à un calcul de distance sur l'ensemble de la table.

```
SELECT post_id,
       VEC_DISTANCE_EUCLIDEAN(embedding, VEC_FromText(%s)) AS distance
FROM wp_articles_embeddings
ORDER BY distance ASC
LIMIT 10;
```

## Ce que cela change par rapport à un service externe

L'avantage le plus net tient à la simplicité opérationnelle : pas de nouvelle facturation par appel, pas de synchronisation à maintenir entre deux systèmes, pas de latence réseau supplémentaire vers un service tiers. La contrepartie est une charge de calcul qui repose sur le serveur de base de données existant, à surveiller sur les sites à fort trafic.

| Critère | MariaDB VECTOR | Service externe dédié |
| --- | --- | --- |
| Latence réseau | Aucune, tout est local | Un aller-retour réseau par requête |
| Coût récurrent | Aucun coût par appel | Facturation à l'usage ou à l'abonnement |
| Volumétrie confortable | Quelques centaines de milliers de vecteurs | Millions de vecteurs sans effort |
| Maintenance | Une seule base à sauvegarder | Un système supplémentaire à surveiller |

### Nos mesures sur ce projet

Sur environ 4 000 articles indexés, une recherche par similarité répond en moins de 50 millisecondes sur notre infrastructure, un résultat largement suffisant pour une fonctionnalité de recherche interactive sur un site de documentation.

> Ne pas ajouter un service externe quand la base existante suffit : c'est une ligne de sauvegarde et de supervision en moins.

## Notre verdict

Pour un volume de contenu raisonnable, le type `VECTOR` de MariaDB évite l'ajout d'un service dédié à la recherche sémantique, sans compromis notable sur la vitesse de réponse. Au-delà de quelques centaines de milliers de vecteurs, une solution spécialisée redevient pertinente, mais pour la grande majorité des sites WordPress, cette approche suffit largement.
