N-grammes
Ce guide couvre la tokenisation et l'analyse N-gramme pour la recherche de sous-chaînes, les requêtes par préfixe et la fonctionnalité d'autocomplétion.
Qu'est-ce que les N-grammes ?
Un N-gramme est une séquence continue de N caractères (ou de jetons) d'une chaîne. Par exemple, les 2-grammes de "hello" sont : "he", "el", "ll", "lo".
L'analyse N-gramme est utile pour :
- Recherche de sous-chaînes (trouver "ell" dans "hello")
- Autocomplétion / suggestions en temps réel
- Correspondance floue sans calcul de distance d'édition
NgramTokenizer
Le NgramTokenizer divise le texte en N-grammes au niveau des
caractères :
from whoosh.analysis import NgramTokenizer
from whoosh import fields
tokenizer = NgramTokenizer(minsize=2, maxsize=4)
schema = fields.Schema(
content=fields.TEXT(analyzer=tokenizer),
)
Paramètres de NgramTokenizer
minsize: Longueur minimale des N-grammes (par défaut2)maxsize: Longueur maximale des N-grammes (par défaut4)
Avec l'exemple ci-dessus, le texte "hello" produit ces 2-4-grammes :
he, hel, hell, el, ell, ello, l, ll, llo, l, lo, o
NgramFilter
Le NgramFilter crée des N-grammes au niveau des mots à partir du
texte tokenisé :
from whoosh.analysis import RegexTokenizer, NgramFilter
analyzer = RegexTokenizer() | NgramFilter(maxsize=2)
Cela produit des grammes au niveau des mots : pour "hello world", il produit ("hello",) et ("hello", "world").
NgramWordAnalyzer
Un analyseur de commodité qui combine NgramTokenizer avec
LowercaseFilter :
from whoosh.analysis import NgramWordAnalyzer
analyzer = NgramWordAnalyzer(minsize=2, maxsize=4)
schema = fields.Schema(
content=fields.TEXT(analyzer=analyzer),
)
Cas d'utilisation
Recherche de sous-chaînes
Avec l'analyse N-gramme, vous pouvez correspondre des sous-chaînes :
from whoosh.qparser import QueryParser
# Index text with N-grams
# Searching for "ell" matches "hello" because "ell" is a substring
qp = QueryParser("content", schema=ix.schema)
q = qp.parse("ell")
results = searcher.search(q)
Correspondance par préfixe
Définissez maxsize à une grande valeur pour créer efficacement des
N-grammes de préfixe :
from whoosh.analysis import NgramWordAnalyzer
# Create N-grams where each word's prefixes become searchable tokens
# e.g., "hello" -> "h", "he", "hel", "hell", "hello"
analyzer = NgramWordAnalyzer(minsize=1, maxsize=10)
Autocomplétion
Les index N-gramme sont couramment utilisés pour l'autocomplétion. Pour une autocomplétion plus avancée avec des N-grammes de bord (edge n-grams), envisrez :
from whoosh.analysis import RegexTokenizer, NgramFilter
from whoosh.query import Prefix
# Index with standard tokenization, then use Prefix queries for autocomplete
analyzer = RegexTokenizer()
schema = fields.Schema(
title=fields.TEXT(stored=True, analyzer=analyzer),
content=fields.TEXT(analyzer=analyzer),
)
# For autocomplete, query with Prefix
from whoosh.qparser import QueryParser
qp = QueryParser("title", schema=ix.schema)
q = Prefix("title", "hel") # Find documents where title starts with "hel"
Comparaison avec les N-grammes de bord (Edge N-grams)
Certains moteurs de recherche prennent en charge les "N-grammes de bord" (uniquement la génération de N-grammes à partir du début des mots). C'est plus efficace en espace pour l'autocomplétion :
- N-grammes complets : "hello" → "he", "el", "ll", "lo", "hel", "ell", ...
- N-grammes de bord : "hello" → "h", "he", "hel", "hell", "hello"
Le NgramTokenizer de Whoosh génère des N-grammes complets (bidirectionnels).
Pour un comportement similaire aux N-grammes de bord, utilisez les
paramètres minsize et maxsize stratégiquement, ou utilisez des
requêtes Prefix sur un champ tokenisé standard.
Considérations de performance
- Les index N-gramme sont généralement beaucoup plus volumineux que les index standard.
- Chaque jeton original produit plusieurs jetons N-gramme, augmentant la taille de l'index.
- Choisissez
minsizeetmaxsizeavec soin pour équilibrer la qualité de recherche et la taille de l'index. - Pour l'autocomplétion, envisenez d'utiliser des requêtes
Prefixsur un champ non-N-gramme pour de meilleures performances.