GH GambleHub

Tecnologia e Infraestrutura → Elasticsearch e pesquisa em texto completo

Elasticsearch e pesquisa em texto completo

1) Papel Elasticsearch

Elasticsearch (ES) é um sistema de busca e análise distribuído baseado em índices invertidos e estruturas invertebradas para agregações. Ela dá:
  • Total: relevância (BM25), morfologia, fuzzy/typo tolerant.
  • Facetas e agregações: cortes rápidos por atributos.
  • Pesquisa híbrida BM25 + kNN vetores (semântica).
  • Velocidade de desenvolvimento: Query DSL, ingest pipelines, um ecossistema rico.

Para iGaming/Fintech: pesquisa de jogos/provedores, promoções e regras, facetas de resposta rápida (provedor, volatilidade, RTP, língua), pesquisa em revistas KYC/AML, análise de logs e alertas.


2) Modelo de dados e muppings

2. 1 Índice e tipos de campo

'text' (campo analisado) é para o texto completo.
'keyword' - valores exatos/agregações/ordenamento.
`date`, `long/double`, `boolean`, `ip`, `geo_point`.
'nested' é um conjunto de objetos com correlação de campos correta.
'dense _ vector' - apresentações vetoriais (embeddings).

2. 2 Estratégia de multi-campo

Guarde o campo em várias vistas: 'name. text' (analisado), 'name. raw` (keyword), `name. ngram '(para cumprimento automático).

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 Nested para facetas

Atributos da vista 'feures': [\name, value 03] 'apareça' nested ', senão as facetas apresentam falsas coincidências.


3) Relevante: BM25, bust e híbrido

3. 1 Clássico (BM25)

Combine os campos com a balança (title ^ 4, tags ^ 2, descrição).
Use 'minimum _ should _ match' para controlar correspondências «ruidosas».

3. 2 Vetores (kNN) + BM25 (rerank)

Embeddings (por exemplo, 384-768) em 'dense _ vector'.
Primeiro kNN por vetor (top 200-500), depois rescore BM25 + bustos de negócios (novidade, RTP, licença da região).

Exemplo de pedido híbrido:
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) Completação automática e dicas

Abordagens:
  • Edge N-gram na parte inferior do 'title'. ngram '(rápido, simplesmente).
  • Complition sugesters ('complition' campo) - dicas rápidas, mas um caminho de indexação separado.
  • Search-as-you-tipo - combina o tocening para iniciar a palavra e as palavras.
Exemplo de dicas:
json
{ "suggest": { "game-suggest": { "prefix": "book o", "completion": { "field": "title_suggest", "fuzzy": { "fuzziness": 1 }}}}}

5) Sinônimos, falhas e multi-linguagem

Sinônimos: carregue o arquivo/lista através do filtro 'synonym'; divida os domínios (casino/esportes).
Falhas: 'fuzziness: AUTO' em 'multi _ match', limite comprimentos e campos. Para as dicas, «fuzzy» em modo de completição.

Multifuncionalismo:
  • Índice-per-local (ru/en/tr/pt-BR) ou esquema de análise múltipla: 'title _ ru', 'title _ en'.
  • Разные analyzers: `russian`, `english`, `turkish`, `portuguese`.
  • Transfira a língua para a chave de routing (roting) para manter os locais quentes mais próximos do usuário.

6) Filtros, facetas e agregações

Para facetas, use «keyword» e «nested» agregados.
Evite campos radicais (ID exclusivo) nas agregações - leve para 'runtime fields' ou vitrines preliminares.

Exemplo de facetas:
json
{
"size": 20,
"aggs": {
"by_provider": { "terms": { "field": "provider", "size": 20 } },
"by_volatility": { "terms": { "field": "volatility" } },
"rtp_hist": { "histogram": { "field": "rtp", "interval": 1 } }
}
}

7) Entrada de dados e limpeza de texto

Ingest pipelines: normalização, extração de campos, geo-encoding, remoção de HTML.
Attachment/ingest-ocr (necessário): indexação de PDF/imagem (atento ao PII).
Lematização: através de analisadores ou pipinas externas (precompute tokens).


8) Chardes, réplicas e ILM

8. 1 Dimensões e charding

Menos chardes, melhor. Objetivo: 10-50 GB por shard para carga mista.
Comece com 'number _ of _ shards: 1-3' e faça o zoom. Réplicas - pelo menos 1 em venda.

8. 2 ILM (Lifecycle)

hot → warm → cold → delete para logs/histórico de promoção.
Compactação (force merge) para segmentos «frios».
Para catálogos e pesquisas por produto, hot «indefinido» com otimização periódica.

8. 3 Algoritmo de migração sem downthame

O novo índice 'games _ v2' → alias 'games' alterna após 'reindex' e backfill. Campos Deprecated - remova gradualmente.


9) Snapshots, DR. e atualizações

Snapshots em armazenamento de objetos (S3/GCS), programação e verificação de recuperação.
Atualizações de roll do nó, verificação de shard allocation awareness (por zona).
Planos DR.: Replicação cruzada (CCR) para índices críticos (guias, diretórios).


10) Segurança e PII

Entre o cliente e o cluster.
RBAC: papéis para índice/operação; Dave/Estágio/Prod - separados.
PII/PCI: Não indexe campos com dados pessoais sem necessidade; use camuflagem ingest.
Right to be forgotten: guarde links de documentos para remover por user _ id; soft-delete + reindex/anúncio.


11) Observabilidade e pesquisa SLO

Métricas:
  • P50/P95/P99 latency em query, erros 4xx/5xx.
  • Cache hit (query cache / shard request cache).
  • Heap usage, GC паузы, segment merges, threadpools (search/write).
  • Hot shards/hot nodes, rejections.
  • KNN: `graph_hits`, `search_k`, latency, recall@k.
Exemplos SLO:
  • Pesquisa de jogos P95 ≤ 200 ms, erros <0. 5% na janela de 30 min.
  • Dicas: P95 ≤ 80 ms.
  • Híbrido KNN: P95 ≤ 350 ms para resultados top-20.

12) FinOps: custo e desempenho

Tamanho do índice: economize com o torneamento, desabilite «fielddata» desnecessário, use «doc _ values» apenas onde desejar.
Segmentos: Planeje uma política merge, não suporte «esmagamento».
KNN mais caro em RAM/CPU: limite dims, 'num _ candidates', pré-filter em BM25.
Campos quentes em RAM: monitor field data/heap; leve as agregações «pesadas» para índices individuais.


13) Exemplos de solicitação

13. 1 Multi-texto cheio com busto

json
{
"query": {
"multi_match": {
"query": "book of",
"fields": ["title^4","title.ngram^2","tags^2","description"]
}
},
"sort": ["_score", { "released_at": "desc" }]
}

13. 2 Filtros + facetas

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 Nested filtragem de atributos

json
{
"query": {
"nested": {
"path": "features",
"query": { "bool": {
"must": [
{ "term": { "features.name": "volatility" }},
{ "term": { "features.value": "high" }}
]
}}
}
}
}

13. 4 Pesquisa por logs (ECS) com highlight

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-tenente e isolamento

Índice por tenante (melhor) ou campo 'tenant _ id' + filtro LCA (mais caro em agregações).
Routing por 'tenant _ id' para localização de chardes.
Limite as solicitações do tenante a limites/temporizações, 'query. phase` guard-rails.


15) Folha de cheque de implementação

1. Esquema: 'text/keyword/nested' + multipla, 'dense _ vector', se necessário.
2. Analisadores per-linguagem, sinônimos, edge-ngram para completação automática.
3. Relevante: BM25 bustes + híbrido kNN→rescore.
4. Facetas: keyword/nested, agregados apenas em campos «saudáveis».
5. Indexação: ingest pipelines (normalização), download.
6. Charding: comece por pequeno, alias de deslocamento, ILM para logs «longos».
7. DR.: programação snapshots, verificação de recuperação, CCR para índices críticos.
8. Segurança: TLS, RBAC, camuflagem PII, política de remoção.
9. Observabilidade latency, heap/GC, cachê hit, hot shards, rejeções.
10. FinOps: tamanho do índice, kNN da parametrização, desativação dos demais 'doc _ values/fielddata'.


16) Anti-pattern

Um índice para todos: domínios diferentes (diretório, logs, transações) exigem configurações diferentes.
O inútil 'fuzziness: AUTO' em todos os campos → lento e barulhento.
Os sinônimos «comem o significado» são não separar os domínios dos dicionários.
Sem nested onde você precisa de amarras de campos → facetas falsas.
Excesso de chardes (um por documento) - Custos gerais do cluster state.
Não usar alias nas migrações - interrupções e links «batidos».
A indexação PII «tal como está» - riscos regulatórios e reindexos caros.


17) Contexto iGaming/fintech: receitas rápidas

Pesquisa de jogos: 'multi _ match' com 'title ^ 4', 'tags ^ 2', facetas de provedor/volátil, filtros de região/moeda, híbrido com vetores para 'tópicos' (como 'egito', 'frute classic').
Promoção/bónus: sinônimos («frisas», «free spins»), filtros de data 'ativo _ from/ativo _ to', dicas através da compressão.
KYC/AML Revistas: ECS, texto completo por 'mensagem', agregação por 'rule _ name', 'country', anomalias por '@ timestamp' histograma.
Guia do provedor: campos de faceta e triagem keyword; descrições de texto - 'text' com morfologia.
Páginas de regulação: campos de língua múltipla, 'search _ as _ you _ tipo' para dicas suaves.


Resultado

Uma pesquisa eficaz no Elasticsearch não é apenas «incluir BM25»: são analisadores e muppings corretos, multipla e nested, híbrido VM25 + vetores, facetas e agregações cuidadosas, disciplina de charding e ILM, SLO claro e observabilidade, bem como segurança e FinOps. Com estes princípios, a sua busca será rápida, relevante e previsível - e resistirá aos picos de tráfego da plataforma de alimentos.

Contact

Entrar em contacto

Contacte-nos para qualquer questão ou necessidade de apoio.Estamos sempre prontos para ajudar!

Iniciar integração

O Email é obrigatório. Telegram ou WhatsApp — opcionais.

O seu nome opcional
Email opcional
Assunto opcional
Mensagem opcional
Telegram opcional
@
Se indicar Telegram — responderemos também por lá.
WhatsApp opcional
Formato: +indicativo e número (ex.: +351XXXXXXXXX).

Ao clicar, concorda com o tratamento dos seus dados.