GH GambleHub

Filtrage et recherche en texte intégral

1) Pourquoi avez-vous besoin d'une couche de recherche

Le filtrage et la recherche en texte intégral (FTS) permettent un accès rapide aux données « par sens », et pas seulement par clés primaires. Une couche de recherche correctement conçue combine :
  • Filtres stricts (catégories, dates, prix, droits d'accès)
  • Texte intégral (match lexical et classement)
  • Facettes (unités de navigation)
  • Classement hybride (BM25/TF-IDF + embeddings vectoriels)
  • Protocoles fiables (pagination par les curseurs, tokens TTL, cross-sharding)

2) Tableau architectural

Composants :

1. Ingest/ETL → normalisation, déduplication, enrichissement, construction de champs pour l'index.

2. L'indexeur → l'index inverse (lexèmes → documents), les structures de colonne, l'index vectoriel (HNSW/IVF-PQ).

3. Query Layer → parser des requêtes, appliquer des filtres/droits d'accès, Chard's Planner, k-way merge.

4. Ranker → BM25 + (opz.) LTR/Neural re-rank.

5. Serving → cache, curseurs, facettes, highlights, plaques automatiques.

6. Observabilité → métriques de latence, qualité, expériences A/B.

3) Modèle de données et index

3. 1 Champs et analyseurs

Types : keyword (match régulier), text (analysé), numeric/date/geo, vecteur.
Analyseurs : Tokenisation, normalisation (lowercase, Unicode NFKC), filtres (stop-word, stemming/lemmatisation).
Multilinguisme : analyseurs par champ (ru, uk, en) ; Analyse UCI ; translittération ; prise en compte de la diacritique.

3. 2 Index inverse (sparse)

Structure : term → posting list (docID, term freq, positions).
Classement : BM25 (ou TF-IDF classique) avec boosts de terrain.

3. 3 Index vectoriel (dense)

Embeddings de texte (par exemple 384-1024).
Structures ANN : HNSW, IVF-PQ, Flat (pour les petits ensembles).
Proximité cosinus/produit inner ; étalonnage avec BM25 (hybride).

3. 4 Facettes et agrégats

Préemballage/colonnette des valeurs pour les count-s rapides.
Facettes hiérarchiques (catégorie/sous-catégorie).
Fourchettes (bins de prix, dates).

4) Demandes : filtres + texte intégral + tri

4. 1 Contrats API (REST)

Demande :

GET /v1/search? q = classic slots & limit = 20 & cursor =... & sort = score: desc, created _ at: desc
&filters=brand:("NetEnt","EGT"); price:[10 TO 50];published_at:[2024-01-01 TO ]
&facets=brand,year,price:range(0,10,20,50,100)
Réponse (fragment) :
json
{
"items": [ { "id":"...", "title":"...", "score": 12. 3, "highlight": { "content": ["..."] } } ],
"facets": { "brand": [{"value":"NetEnt","count":123},...] },
"page": { "limit":20, "has_more":true, "next_cursor":"opaque-token" }
}

4. 2 GraphQL (simplifié)

graphql type Query {
search(query: String!, filter: SearchFilter, first: Int, after: String, sort: [Sort!]): SearchConnection!
}

4. 3 gRPC

proto message SearchRequest {
string query = 1;
map<string,string> filters = 2;
int32 page_size = 3;
string page_token = 4; // курсор repeated string facets = 5;
}

5) Traitement du langage naturel (NLP)

Tokenization/normalisation : Unicode-sûr, compte des tirets/apostrophes.
Mots stop : listes personnalisées par langue.
Stemming vs lemmatization : pour ru/uk mieux lemmatization (qualité> vitesse).
Synonymes : dictionnaires bidirectionnels/directionnels ; versions des dictionnaires avec TTL.
Fautes d'impression (fuzzy) : Damerau-Levenshtein avec limite de distance et boosts de coïncidence exacte.
N-grams/edge-ngrams : pour la plaque automatique et les indices.
Translittération : « shch » ↔ « sh », « kiev/kyiv » sont les règles de correspondance.

6) Pertinence et classement

6. 1 Scoring lexical de base

BM25 avec le paramètre 'k1', 'b' par collection.
Boosters par champs (titre ^ 3, tags ^ 1. 5, body^1).
Fraîcheur : 'score + = freshness_boost (decay (created_at))'.

6. 2 Signaux comportementaux

Click-through rate, dwell time, enregistrer dans les favoris (avec bayas anti-position).
Déduplication : Scale de documents avec un contenu ~ identique (MinHash/SimHash).

6. 3 Learning-to-Rank (LTR)

Fichi : BM25 par les champs, la longueur, la fraîcheur, la popularité, la correspondance de la phrase, le score de position.

Modèles : LambdaMART/XGBoost ; métriques hors ligne NDCG @ k, MAP, Precision @ k ; A/B en ligne

6. 4 Neuro-réarrangement

En deux étapes : recall (BM25/ANN) → top-N (par exemple 200) → cross-encoder rerank.
Comptabilisation des coûts : time budget, fallback sans neuro étape à la charge.

6. 5 Recherche hybride (sparse + dense)

Soit fusion (normalisation des pelles et somme), soit multi-stage (dense comme rerank).
L'étalonnage est important : min-max/z-score/quantile mapping.

7) Filtrage, facettes et accès

7. 1 Filtres

Opérateurs : '=', 'IN', plages, préfixes, geo-bounding box/geo-distance.
Combinaisons : 'AND' par filtres, 'OR' à l'intérieur d'une pluralité de valeurs (marque IN...).
Sécurité typique : les champs numériques ne sont pas analysés comme du texte.

7. 2 Facettes

Bon marché par structure préconçue.
Les facettes « appliquées » montrent les variantes restantes (post-filter facetting).

7. 3 Accès/multi-ténacité

Les filtres de sécurité sont intégrés jusqu'au classement (pré-filtre).
ABAC/RBAC du champ dans le document (« tenant _ id », « visibility », « acl »).
Le jeton de requête est signé ; dans le multitenant, le filtre automatique "tenant _ id'.

8) Pagination, curseurs et consistance

Pagination par un seek-curseur par '(score, tie-breaker)' ou par '(created_at, id)' lors du tri temporel.
Opaque 'page _ token' c HMAC et TTL.
Consistance : near-real-time (NRT) de l'index : retard 0. 5-2 avec entre l'enregistrement et la visibilité. Documentez-le en SLA.
Cross-shard : recherche locale → k-way merge par ordre global, curseurs per-shard dans le token.

9) Remplissage automatique et conseils

Suggesters: prefix-trie / edge-ngrams по полю `title`.
Queries populaires : journal de clics → indices de popularité + personnalisation (segments).
Spell-as-you-type : recherche fuzzy rapide avec limitation de distance '<= 1'.

Exemple REST :

GET /v1/suggest? q=kaz&limit=8&locale=ru
→ ["casino," "casual games,..."]

10) Highlights et Snappets

L'index de position → l'extraction des phrases avec des correspondances.
Blindage HTML, limite de longueur, fusion de tranches adjacentes.
Classement des captures en fonction de la densité des termes pertinents.

11) Performances, cache et SLO

Index : segments chauds en mémoire ; compression des postings ; doc values pour les facettes.
Cache : L1 (processus), L2 (Redis), cache de facettes/agrégats ; invalidité selon la version de l'index.
SLO : P95 <150-200 ms à 'k <= 20', P99 <500 ms ; disponibilité 99. 9%.
Backpressure : réduction 'k', arrêt de l'étape neuro en cas de surcharge.
Limite de taux sur la clé API/utilisateur/tenant.

12) Observabilité et métriques de qualité

Techniques :
  • `search_latency_ms` (P50/P95/P99), `qps`, `timeouts`, `error_rate`
  • `cache_hit_ratio`, `facet_cache_hit`, `rerank_share`
  • `shard_fanout`, `merge_time_ms`, `ann_recall@k`
Qualité (hors ligne) :
  • NDCG @ k, MAP, MRR, Recall @ k, Precision @ k sur les échantillons marqués.
En ligne :
  • CTR@k, sCTR (satisfied clicks), dwell time, отказ (pogostick rate).

A/B : enregistrer les métriques « guardrail » (latence, erreurs) + cibles (NDCG proxy).

13) Tests

Relevance unit tests : vérifier les matchs attendus pour les demandes clés.
Property-based : résistance aux erreurs typographiques/synonymes/langues.
Pagination : pas de doublons à la limite des pages (seek-contrats).
Sécurité : les filtres d'accès sont toujours appliqués (même sur faset-count).
Régressions des dictionnaires : versionation des synonymes et des règles fuzzy.

14) Sécurité et vie privée

Les champs avec PII ne sont pas indexés comme text ; stocker séparément/chiffrer.
Réduisez au minimum les textes source stockés (store = false, champs de sortie uniquement).
Query privacy : ne pas loger les demandes brutes avec PII ; anonymisation/hachage.
Multi-tenant : isolation stricte des index ou filtre obligatoire "tenant _ id'.

15) Migrations et interopérabilité

La double écriture et la commutation progressive du schéma d'index (v1→v2).
Compatibilité des analyseurs : vous ne pouvez pas encore réindexer les anciennes chaînes.
Rotation des dictionnaires synonymes/mots stop : 'version', 'activated _ at', rollback.

16) Recettes pratiques

16. 1 Recherche lexicale classique (BM25)

Champs : 'title ^ 3', 'tags ^ 2', 'body ^ 1'.
Analyseurs : langage spécifique + lemmatisation.
Fuzzy pour les requêtes courtes ('<= 3' tokens), 'fuzz....= 1'.

16. 2 Hybride sparse + dense

1. Recherche ANN par embedding de requête (k = 200)

2. Combiner avec top-200 BM25

3. Calibrer et fusionner (Reciprocal Rank Fusion)

4. Prenez top-N (N = 20), optionnellement - rerank cross-encoder avec un budget suffisant.

16. 3 Navigation à facettes du catalogue

Un pré-filtre rigide sur les droits/tenants

Facettes post-filtrage (counts avec filtres actifs)

Tri : par pertinence ou par domaine d'activité (prix/nouveauté)

17) Exemples de demandes (pseudo-DSL)

Filtres et triage :
json
{
"query": "live casino,"
"filters": {
"country": ["EE","LV","LT"],
"license": ["MGA","UKGC"],
"launched_at": {"gte": "2023-01-01"}
},
"sort": ["_score:desc","launched_at:desc"],
"facets": ["country","license"],
"page": {"limit": 20, "cursor": "opaque"}
}
Géopoisque :
json
{
"query": "casino",
"geo": {"lat": 59. 437, "lon": 24. 753, "radius_km": 50}
}
Plaque automatique :
json
{ "prefix": "evo", "field": "brand_suggest", "limit": 8 }

18) Modèles UX

Puces de filtres actifs + « tout réinitialiser ».
Résultats vides : montrer « essayer... » (synonymes, supprimer le filtre).
« Conseils à zéro » : demandes/catégories populaires.
Pagination par le curseur (bouton « Plus ») et le scroll infini ; indicateur fixe des filtres appliqués.
Interrupteurs individuels « tenir compte des erreurs typographiques », « correspondance exacte de la phrase ».

19) Erreurs fréquentes et anti-modèles

L'absence de tie-breaker lors du tri des prises/sauts →.
Les facettes sans compter les filtres actifs → les « faux » counts.
Appliquer des filtres d'accès après le classement.
Mélanger différentes langues avec un analyseur unique.
Pagination profonde OFFSET/LIMIT au lieu du seek-curseur.
Fuzzy illimité → explosion par latence.

20) Chéquiste de mise en œuvre

1. Définissez les champs et leurs types, affectez les analyseurs per-local.
2. Concevoir l'indice inverse + (opz.) l'ANN vectorielle.
3. Implémentez un parser de requête et des filtres d'accès sécurisés (pré-filtre).
4. Ajustez les boosts de BM25 et de terrain ; branchez les facettes.
5. Entrez les curseurs (opaque, HMAC, TTL) et k-way merge par chardons.
6. Ajoutez une plaque automatique, des highlights, un blindage sécurisé.
7. Métriques : latence, NDCG @ k, CTR ; Cache L1/L2.
8. Cadre A/B pour le réglage de la pertinence.
9. Documenter SLA : délai NRT, limites 'limit', garantie de cohérence.
10. Plan de migration : versions de l'index, des dictionnaires et des analyseurs.

Une couche bien conçue de filtrage et de recherche plein texte est non seulement un index rapide, mais aussi un contrat de protocole clair avec des curseurs, une sécurité, un UX prévisible et une pertinence mesurable. Cette approche s'étend de milliers à des milliards de documents et prend en charge à la fois la recherche lexicale classique et les scénarios hybrides modernes avec le classement neuronal.

Contact

Prendre contact

Contactez-nous pour toute question ou demande d’assistance.Nous sommes toujours prêts à vous aider !

Telegram
@Gamble_GC
Commencer l’intégration

L’Email est obligatoire. Telegram ou WhatsApp — optionnels.

Votre nom optionnel
Email optionnel
Objet optionnel
Message optionnel
Telegram optionnel
@
Si vous indiquez Telegram — nous vous répondrons aussi là-bas.
WhatsApp optionnel
Format : +code pays et numéro (ex. +33XXXXXXXXX).

En cliquant sur ce bouton, vous acceptez le traitement de vos données.