« boulen M8 inpx » : ce que votre moteur a compris, et pourquoi il vous le montre
Un moteur qui se trompe sans expliquer est impossible à corriger. Voici une vraie requête, avec ses fautes : « boulen M8 inpx ».
Une cascade en deux niveaux, du même côté pour les documents et les requêtes
Des règles organisées en niveaux : le niveau 1 reconnaît les motifs bruts d'un texte — « m8 » devient un diamètre, un « 20 » qui suit un « x » devient une longueur. Le niveau 2 compose ces annotations entre elles : diamètre et longueur ensemble donnent une référence complète.
« m8x20 » → DIAM_M8 + LONG_20 → VIS_M8X20
« M8 x 20 — A2 » (fiche produit) → même résultat
Documents et requêtes traversent la même cascade : la correspondance se fait dans un espace partagé, pas seulement sur les mots. Une requête tapée d'une façon et une fiche produit rédigée d'une autre aboutissent à la même annotation.
« boulen M8 inpx », terme par terme
| Terme | Résultat | Note |
|---|---|---|
| boulen | boulon | faute rattrapée, score pondéré à 60 % |
| M8 | diamètre M8 | reconnu comme une cote, pas comme du texte |
| inpx | inox | faute rattrapée, score pondéré à 60 % |
Boulon TF M8 x 50 inox A4 arrive en tête, et le raisonnement complet est visible : deux fautes rattrapées avec un score pondéré, une cote reconnue sans pondération puisque ce n'est pas une faute.
Le champ qui dit pourquoi
Chaque résultat inclut un champ matched qui liste pourquoi il sort — un terme trouvé, une faute corrigée, une annotation partagée. Sur une recherche « m8x20 inox », la fiche « Vis tête hexagonale », référencée M8 x 20 — A2, ne porte que des annotations dans son matched, aucun terme :
"matched": ["annotation #VIS_M8X20", "annotation #DIAM_M8", "annotation #LONG_20"]
La fiche ne partage pourtant aucun mot avec la requête — sa référence s'écrit avec espaces et tiret, jamais m8x20 collé. C'est la cascade, pas le texte, qui les rapproche. matched reste aussi l'outil de diagnostic quand un résultat surprend : plutôt que deviner, on lit ce qui a effectivement compté.
Le surlignage, ou la même explication dans l'interface
include_highlights (booléen, faux par défaut) ajoute à chaque résultat les positions exactes des correspondances trouvées par cette requête précise, pour chaque champ concerné — ref, name, description — de quoi entourer le fragment pertinent d'un simple <mark> sans le recalculer soi-même :
{
"product": {
"ref": "VIS-M8X20-INOX-A2",
"name": "Vis à métaux M8x20 inox A2, lot de 50"
},
"highlights": {
"ref": [[0, 3], [4, 9], [10, 14]],
"name": [[0, 3], [13, 18], [19, 23]]
}
}
Non demandé, le calcul ne coûte rien ; demandé, il ne tourne qu'une fois par requête, jamais par produit candidat. Un champ sans correspondance pour cette requête n'apparaît simplement pas — jamais un tableau vide à filtrer soi-même. Un point technique à ne pas manquer en l'implémentant : les positions sont en points de code Unicode. Pour la quasi-totalité des titres produits réels, c'est identique à l'indexation native de votre langage — Python indexe déjà par point de code. En JavaScript, natif en unités UTF-16, Array.from(texte) reste nécessaire face à texte[i] dans le seul cas où ça diverge réellement : un émoji ou un caractère hors du plan de base Unicode.
Le surlignage répond à la même logique diagnostique, avec une règle que la doc énonce explicitement, trois fois : il reflète ce que cette recherche a réellement déclenché, jamais toutes les caractéristiques du produit. Une matière, une norme, un type de tête de vis mentionnés plus loin dans une description restent indexés et cherchables, mais ne s'allument que si la requête les a fait intervenir.
Pour la suite
Le champ matched est disponible sur toute réponse, sans configuration. Le surlignage, lui, s'active à la demande avec include_highlights: true — à activer côté widget dès que l'interface a besoin de montrer, pas seulement de trouver. L'endpoint recherche en donne un exemple de réponse complet.