Tehnologie și infrastructură → Elasticsearch și căutare Full-Text
Căutarea elastică și căutarea integrală a textului
1) Elasticsearch rol
Elasticsearch (ES) este un sistem distribuit de căutare și analiză bazat pe indici inversați și structuri de coloane pentru agregări. Acesta oferă:- Text complet: relevanță (BM25), morfologie, toleranță fuzzy/typo.
- Fațete și agregate: felii rapide după atribute.
- Căutare hibridă: BM25 + vector kNN (semantică).
- Viteza de dezvoltare: interogare DSL, ingera conducte, ecosistem bogat.
Pentru iGaming/fintech: căutați jocuri/furnizori, promoții și reguli, fațete cu reacție rapidă (furnizor, volatilitate, RTP, limbă), căutați reviste KYC/AML, jurnale de analizare și alerte.
2) Modelul de date și mapări
2. 1 Indice de câmp și tipuri
„text” pentru textul integral.
„cuvânt cheie” - valori exacte/agregări/sortare.
'data', 'long/double', 'boolean', 'ip', 'geo _ point'.
„imbricat” - matrice de obiecte cu corelare corectă a câmpului.
'dense _ vector' - reprezentări vectoriale (încorporări).
2. 2 Strategie pe mai multe câmpuri
Stocați câmpul în mai multe vizualizări: "nume. text „,” nume. raw '(cuvânt cheie),' nume. ngram '(pentru auto-finalizare).
json
{
"mappings": {
"properties": {
"title": {
"type": "text",
"analyzer": "ru_morph",
"fields": {
"raw": { "type": "keyword", "ignore_above": 256 },
"ngram": { "type": "text", "analyzer": "edge_ngram_2_20" }
}
},
"provider": { "type": "keyword" },
"tags": { "type": "keyword" },
"rtp": { "type": "float" },
"released_at": { "type": "date" },
"lang": { "type": "keyword" },
"embedding": { "type": "dense_vector", "dims": 384, "index": true, "similarity": "cosine" }
}
},
"settings": {
"analysis": {
"filter": {
"ru_stop": { "type": "stop", "stopwords": "_russian_" },
"ru_stemmer": { "type": "stemmer", "language": "russian" },
"syn_ru": { "type": "synonym", "lenient": true, "synonyms": [
"слот,игровой автомат => слот",
"джекпот,суперприз => джекпот"
] }
},
"analyzer": {
"ru_morph": {
"type": "custom",
"tokenizer": "standard",
"filter": ["lowercase", "ru_stop", "ru_stemmer", "syn_ru"]
},
"edge_ngram_2_20": {
"type": "custom",
"tokenizer": "edge_ngram",
"filter": ["lowercase"],
"char_filter": [],
"tokenizer": "edge_ngram"
}
},
"tokenizer": {
"edge_ngram": { "type": "edge_ngram", "min_gram": 2, "max_gram": 20 }
}
}
}
}
2. 3 Imbricate pentru fațete
Atribute ale formularului „caracteristici: [{nume, valoare}]” design „imbricat”, în caz contrar fațetele vor da meciuri false.
3) Relevanță: BM25, impuls și hibrid
3. 1 Clasice (BM25)
Combină câmpurile cu greutăți (titlul ^ 4, etichetele ^ 2, descriere).
Utilizați „minim _ should _ match” pentru a controla meciurile zgomotoase.
3. 2 Vectori (kNN) + BM25 (rang)
Încorporări (ex. 384-768) în „dense _ vector”.
În primul rând kNN de vector (top 200-500), apoi rescore BM25 + afaceri stimulează (noutate, RTP, regiune licență).
json
{
"knn": {
"field": "embedding",
"query_vector": [/... /],
"k": 400, "num_candidates": 2000
},
"query": {
"bool": {
"should": [
{ "multi_match": {
"query": "египетские слоты джекпот",
"fields": ["title^4","tags^2","description"],
"type": "best_fields",
"minimum_should_match": "60%"
}}
],
"filter": [
{ "term": { "region": "TR" }},
{ "range": { "rtp": { "gte": 94.0 }}}
]
}
},
"rescore": {
"window_size": 400,
"query": {
"rescore_query": {
"function_score": {
"query": { "match_all": {} },
"boost_mode": "sum",
"functions": [
{ "gauss": { "released_at": { "scale": "180d", "offset": "30d", "decay": 0.5 } } },
{ "field_value_factor": { "field": "popularity", "factor": 0.2, "modifier": "log1p" } }
]
}
}
}
},
"highlight": { "fields": { "title": {}, "description": {} } }
}
4) Auto-finalizare și solicitări
Abordări:- Edge N-gram pe subfield' titlu. ngram '(rapid, simplu).
- Sugestii de completare (câmpul „finalizare”) - sugestii rapide, dar o cale de indexare separată.
- Search-as-you-type - combină tokenizarea pentru a porni cuvinte și fraze.
json
{ "suggest": { "game-suggest": { "prefix": "book o", "completion": { "field": "title_suggest", "fuzzy": { "fuzziness": 1 }}}}}
5) Sinonime, greșeli de ortografie și multilingvism
Sinonime: încărcați fișierul/lista prin filtrul „sinonim”; domenii separate (cazinou/sport).
Greșeli de ortografie: 'fuzziness: AUTO' în 'multi _ match', limită la lungime și câmpuri. Pentru solicitări - modul de finalizare „fuzzy”.
- Index-per-locale (ru/en/tr/pt-BR) sau circuit multi-analyzer: 'title _ ru', 'title _ en'.
- analizoare Разные: 'rusa', 'engleza', 'turca', 'portugheza'.
- Mutați limba în tasta de rutare pentru a menține locațiile fierbinți mai aproape de utilizator.
6) Filtre, fațete și agregate
Pentru fațete, utilizați „cuvânt cheie” și „imbricat” agregare.
Evitați câmpurile cardinale (ID-uri unice) în agregări - aduceți-le la 'câmpuri runtime' sau pre-ferestre.
json
{
"size": 20,
"aggs": {
"by_provider": { "terms": { "field": "provider", "size": 20 } },
"by_volatility": { "terms": { "field": "volatility" } },
"rtp_hist": { "histogram": { "field": "rtp", "interval": 1 } }
}
}
7) Introducerea datelor și compensarea textului
Ingera conducte: normalizare, extracție câmp, geo-codificare, HTML ștergere.
Atașament/ingerare-ocr (după cum este necesar): indexare PDF/imagine (atenție cu PII).
Lematizare: prin analizoare sau conducte externe (token-uri precompute).
8) Cioburi, replici și ILM
8. 1 Dimensiuni și Sharding
Mai puţine cioburi sunt mai bune. Țintă: 10-50GB per ciob pentru sarcini mixte.
Începeți cu „number _ of _ shards: 1-3”, scară de fapt. Replici - cel puțin 1 în vânzări.
8. 2 ILM (ciclu de viață)
fierbinte → cald → rece → șterge pentru jurnalele/istorie promo.
Forţa fuzionează pentru segmente reci.
Pentru cataloage și căutare de produse - „perpetuu” fierbinte cu optimizare periodică.
8. 3 Algoritm de migrare fără downtime
Noul index 'games _ v2' → alias 'jocuri' switch-uri după 'reindex' și backfill. Câmpuri deprimate - eliminați treptat.
9) Instantanee, DR și actualizări
Instantanee pentru a obiecta de stocare (S3/GCS), programa și restabili verifica.
Actualizări ale nodurilor, verificarea conștientizării alocării cioburilor (pe zone).
Planuri DR: replicare cross-region (CCR) pentru indici critici (directoare, directoare).
10) Siguranță și PII
TLS/mTLS între client și cluster.
RBAC: roluri per index/operație; Dev/Stage/Prod - separat.
PII/PCI: nu indexați inutil câmpurile cu date cu caracter personal; Utilizați ingera mascare.
Dreptul de a fi uitat: păstrați link-uri către documente pentru ștergerea de către user_id; soft-delete + reindex/anunț.
11) Observabilitate și căutare SLO
Măsurători:- P50/P95/P99 latență la interogare, erori 4xx/5xx.
- Cache lovit (interogare cache/ciob cerere cache).
- Utilizare Heap, GC паузы, segment fuzionează, threadpools (căutare/scrie).
- Cioburi fierbinți/noduri fierbinți, respingeri.
- KNN: 'graph _ hits',' search _ k ', latență, rechemare @ k.
- În căutare de jocuri: P95 ≤ 200 ms, erori <0. 5% în fereastra de 30 de minute.
- Sfaturi: P95 ≤ 80 ms.
- KNN hibrid: P95 ≤ 350ms pentru rezultate de top-20.
12) FinOps: cost și performanță
Dimensiunea indexului: salvați tokenizarea, dezactivați „fieldata” inutilă, utilizați „doc _ values” numai acolo unde este necesar.
Segmente: politica de unificare a planului, nu permit „împărțirea”.
KNN este mai scump în RAM/CPU: limit dims, 'num _ candidats', pre-filtru pe BM25.
Câmpuri fierbinți în memorie RAM: monitorizați datele câmpului/heap; ia agregări „grele” în indici separați.
13) Cereri de probă
13. 1 Multi-field full-text cu impuls
json
{
"query": {
"multi_match": {
"query": "book of",
"fields": ["title^4","title.ngram^2","tags^2","description"]
}
},
"sort": ["_score", { "released_at": "desc" }]
}
13. 2 Filtre + fațete
json
{
"query": {
"bool": {
"must": [{ "match": { "title": "египет" }}],
"filter": [
{ "terms": { "provider": ["Novomatic","PragmaticPlay"]}},
{ "range": { "rtp": { "gte": 95 }}}
]
}
},
"aggs": {
"by_provider": { "terms": { "field": "provider" } },
"by_year": { "date_histogram": { "field": "released_at", "calendar_interval": "year" } }
}
}
13. 3 Filtrarea atributelor imbricate
json
{
"query": {
"nested": {
"path": "features",
"query": { "bool": {
"must": [
{ "term": { "features.name": "volatility" }},
{ "term": { "features.value": "high" }}
]
}}
}
}
}
13. 4 Căutare jurnal (ECS) cu evidențiere
json
{
"query": {
"bool": {
"must": [{ "match_phrase": { "message": "payment declined" }}],
"filter": [
{ "term": { "service.name": "payments" }},
{ "range": { "@timestamp": { "gte": "now-1h" }}}
]
}
},
"highlight": { "fields": { "message": { "number_of_fragments": 0 } } }
}
14) Multi-chiriaș și izolare
Index pentru chiriaș (mai bine) sau câmp "chiriaș _ id' + filtru ACL (mai scump pe agregate).
Rutare prin "chiriaș _ id' pentru a localiza cioburi.
Limitați cererile chiriașilor la limite/termene, "interogare. şine de pază.
15) Lista de verificare a implementării
1. Schema: 'text/cuvânt cheie/imbricat' + mai multe câmpuri, 'dens _ vector' dacă este necesar.
2. Analizoare per limbaj, sinonime, edge-ngram pentru auto-finalizare.
3. Relevanţă: BM25 stimulează + kNN→rescore hibrid.
4. Fațete: cuvânt cheie/imbricat, agregare numai pentru câmpurile „sănătoase”.
5. Indexare: ingera conducte (normalizare), încărcare lot.
6. Sharding: porniți mici, alias pentru mișcare, ILM pentru jurnalele „lungi”.
7. DR: program instantanee, verificare recuperare, CCR pentru indici critici.
8. Securitate: TLS, RBAC, mascare PII, politica de ștergere.
9. Observabilitate: latență, heap/GC, cache hit, cioburi fierbinți, respingeri.
10. FinOps: dimensiunea indexului, parametrizarea kNN, dezactivarea extra 'doc _ values/fieldata'.
16) Anti-modele
Un index „pentru toți”: diferite domenii (director, jurnale, tranzacții) necesită setări diferite.
Necugetat „fuzziness: AUTO” → încet și zgomotos în toate domeniile.
Sinonime „mănâncă sensul”: nu separați domeniile dicționarului.
Fără imbricate în cazul în care pachete de câmp → fațete false sunt necesare.
Prea multe cioburi (unul pe document) - starea de cluster deasupra capului.
Neutilizarea aliasului în timpul migrațiilor - timpi de nefuncționare și legături rupte.
Indexarea PII „așa cum este” - riscuri de reglementare și reindexuri costisitoare.
17) Context iGaming/fintech: Rețete rapide
Căutați jocuri: 'multi _ match' cu boost 'title ^ 4', 'tags ^ 2', fațete după furnizor/volatilitate, filtre după regiune/monedă, hibrid cu vectori pentru "subiecte" (de exemplu, "Egipt'," fruit classic ").
Promo/bonusuri: sinonime („freespins”, „freespins”), filtre de date „active _ from/active _ to”, sfaturi prin finalizare.
Jurnalele KYC/AML: schema ECS, textul integral prin 'mesaj', agregările prin 'rule _ name', 'country', anomalii prin '@ timestamp' histogramă.
Director furnizor: câmpuri de cuvinte cheie pentru fațete și sortimente; descrieri text - „text” cu morfologie.
Pagini de reglementare: câmpuri multilingve, 'search _ as _ you _ type' pentru sugestii moi.
Rezultat
Căutarea eficientă pe Elasticsearch nu este doar „porniți BM25”: acestea sunt analizoarele și cartografiile potrivite, multifields și imbricate, un hibrid de BM25 + vectori, fațete și agregate îngrijite, disciplina de sharding și ILM, SLO-uri clare și observabilitate, precum și siguranța și Fin Ops. Cu aceste principii, căutarea dvs. va fi rapidă, relevantă și previzibilă - și va rezista la vârfuri în traficul platformei de produse.