Filtrar e pesquisar em texto completo
1) Por que precisa de uma camada de busca
A filtragem e a busca por texto completo (FTS) permitem o acesso rápido aos dados em sentido e não apenas às chaves primárias. A camada de pesquisa adequada combina:- Filtros rigorosos (categorias, datas, preços, permissões)
- Todo o Tex (Jogo vocabulário e classificação)
- Facetas (unidades de navegação)
- Classificação híbrida (BM25/TF-IDF + embeddings vetoriais)
- Protocolos confiáveis (paginação com cursores, TTL de tokens, cross-charding)
2) Pintura arquitetônica
Componentes:1. Ingest/ETL → normalização, dedução, enriquecimento, construção de campos de índice.
2. Indexador → índice inverso (lexemas → documentos), estruturas colinvertebradas, índice vetorial (HNSW/IVF-PQ).
3. Query Layer → parser de consultas, aplicação de filtros/permissões, planeador de chardes, k-way merge.
4. Ranker → BM25 + (opz.) LTR/Neural re-rank.
5. Serving → dinheiro, cursores, facetas, highlights, compacto automático.
6. Observabilidade → métricas de latência, qualidade, experimentos A/B.
3) Modelo de dados e índice
3. 1 Campos e analisadores
Tipos: keyword (correspondência alinhada), text (analisado), numérico/data/geo, vector.
Analisadores: toquenização, normalização (lowercase, unicode NFKC), filtros (pares-palavras, stemming/lemmatização).
Multi-linguagem: per-field analisadores (br, uk, en); Análise ICU; translitoração; A contabilidade da diacrítica.
3. 2 Índice inverso (spars)
Estrutura: term → posting list (docID, term freq, posições).
Classificação BM25 (ou clássico TF-IDF) com bustos de campo.
3. 3 Índice Vetorial (dense)
Embeddings de texto (por exemplo, 384-1024-dimensões).
Estrutura ANN: HNSW, IVF-PQ, Flat (para pequenos conjuntos).
Intimidade de Cosinus/iner produt; calibrar com BM25 (híbrido).
3. 4 Facetas e equipamentos
Armazenamento/colinvertebrado de valores para count-ov rápidos.
Facetas hierárquicas (categoria/subcategoria).
Faixas (bins de preço, datas).
4) Consultas: filtros + texto completo + ordenação
4. 1 Contratos API (REST)
Consulta:
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)
Resposta (fatia):
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 (simplificado)
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) Processamento de linguagem natural (NLP)
Tocenização/normalização: Unicode-seguro, registro de defeitos/apóstrofos.
Pará: listas configuráveis de linguagens.
Emming vs lematização: Para ru/uk é melhor lemmatização (qualidade> velocidade).
Sinônimos: dicionários bidirecionais/direcionados; versões de dicionários com TTL.
Falhas (fuzzy): Damerau-Levenshttein com limitação de distância e correspondência exata.
N-gram/edge-ngrams: para compacto automático e dicas.
Transmissão: «shch», «capa», «kiev/kyiv» - regras de conformidade.
6) Relevância e classificação
6. 1 Varredura vocabulária básica
BM25 com configuração 'k1', 'b' por coleção.
Busts por campo (title ^ 3, tags ^ 1. 5, body^1).
Frescura: 'score + = freshness _ boost (decay (created _ at)'.
6. 2 Sinais comportamentais
Click-through rate, dwell time, preservado para os favoritos (com uma baia anti-posicionamento).
Deduplicação: pente documentos com o mesmo conteúdo (MinHash/SimHash).
6. 3 Learning-to-Rank (LTR)
Fichi: BM25 por campo, comprimento, frescura, popularidade, correspondência por frase, escopo de posição.
Modelos: LambdaMART/XGBoost; as métricas offline NDCG @ K, MAP, Precision @ k; online A/B.
6. 4 Redesenho neural
Recall (BM25/ANNE) → top-N (por exemplo, 200) → cross-encoder ranank.
Contabilidade de custo: orçamento de tempo, falback sem fase neural para carga.
6. 5 Busca híbrida (sparse + dense)
Fusion (normalização e soma) ou multi-estágio (dense como rerank).
A calibragem é importante: min-max/z-score/quantile maping.
7) Filtragem, facetas e acesso
7. 1 Filtros
Operadoras: «=», «IN», faixas, prefixos, geo-bounding box/geo-distância.
Combinações de 'AND' em filtros, 'OR' dentro de vários valores (brand IN...).
Segurança de tipos: os campos de números não são analisados como texto.
7. 2 Facetas
Counts baratos em estruturas pré-concebidas.
As facetas «aplicadas» mostram as opções restantes (post-filter faceting).
7. 3 Acesso/multi-tenência
Os filtros de segurança são integrados antes da classificação (pré-filter).
ABAC/RBAC campos no documento ('tenant _ id', 'visibilidade', 'acl').
O token do pedido foi assinado; em multi-tenante - filtro automático 'tenant _ id'.
8) Paginação, cursores e consistência
A paginação por seek-cursor por '(score, tie-breaker)' ou por '(created _ at, id)' quando o tempo é ordenado.
Opaco 'page _ tocen' c HMAC e TTL.
Consistência: near-real-time (NRT) do índice: atraso 0. 5-2 entre a gravação e a visibilidade. Documente isso no SLA.
Cross Shard: pesquisa local de → k-way merge por ordem global, por-shard cursores em token.
9) Completação automática e dicas
Suggesters: prefix-trie / edge-ngrams по полю `title`.
Popular queries: logs de cliques → dicas de popularidade + personalização (segmentos).
Spell-as-you-tipo: pesquisa rápida fuzzy com limite de distância '<= 1'.
GET /v1/suggest? q=kaz&limit=8&locale=ru
→ ["casino," "casual games,..."]
10) Highlights e snippets
Índice de posição → extração de frases com correspondências.
Ecrã HTML, limite de comprimento, combinação de fatias vizinhas.
Classifica os snippets de acordo com a densidade dos termos relevantes.
11) Desempenho, dinheiro e SLO
Índices: segmentos quentes na memória; compressão postings; doc values para facetas.
Dinheiro: L1 (processo), L2 (Redis), dinheiro de facetas/equipamentos; deficiente na versão do índice.
SLO: P95 <150-200 ms a 'k <= 20', P99 <500 ms; disponibilidade 99. 9%.
Backpressure: redução de 'k', desativação da fase neural com sobrecarga.
Rate limiting na chave API/usuário/tenante.
12) Observabilidade e métricas de qualidade
Tecnométricas:- `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`
- NDCG @ k, MAP, MRR, Recall @ k, Precision @ k em amostras marcadas.
- CTR@k, sCTR (satisfied clicks), dwell time, отказ (pogostick rate).
A/B: Fixe «guarrail» métricas (latência, erros) + alvo (NDCG proxy).
13) Testes
Relevance unit tests: verificação dos jogos esperados para pedidos essenciais.
Property-based: resistência a falhas/sinônimos/línguas.
Paginação: falta de duplicação no limite de página (contratos de seek).
Segurança: os filtros de acesso são sempre aplicados (até mesmo no fse-count).
Regredir dicionários: versionização de sinônimos e regras fuzzy.
14) Segurança e privacidade
Campos PII não são indexados como text; armazenar/criptografar separadamente.
Minimizar os textos originais armazenados (store = falso, apenas os campos de snippets).
Queracy private: Não enxergar pedidos crus com PII; Anonimato/hachagem.
Multi-tenante: isolamento rigoroso dos índices ou filtro obrigatório 'tenant _ id'.
15) Migração e compatibilidade
Versionização do padrão de índice (v1→v2) com registro duplo e alteração gradual.
A compatibilidade dos analisadores é manter as cadeias antigas até ser reindexado.
Rotação de dicionários sinônimos/paras-palavras: «version», «activated _ at», rollback.
16) Receitas práticas
16. 1 Busca vocabulária clássica (BM25)
Campos: 'title ^ 3', 'tags ^ 2', 'body ^ 1'.
Analisadores: linguagem específica + lemmatização.
Fuzzy para consultas curtas ('<= 3' tokens), 'fuzziness = 1'.
16. 2 Híbrido sparse + dense
1. Pesquisa ANN sobre o embedding da consulta (k = 200)
2. Combinar com top-200 BM25
3. Calibrar e fundir
4. Pegue top-N (N = 20), opcionalmente rerank cross-encoder-com orçamento suficiente.
16. 3 Navegação de faces do diretório
Pré-filter rígido sobre direitos/tenente
Facetas pós-filtro (counts com filtros ativos)
Triagem por relevância ou por campo de negócios (preço/novidade)
17) Exemplos de solicitação (pseudo-DSL)
Filtros e triagem: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"}
}
Geopoisca:
json
{
"query": "casino",
"geo": {"lat": 59. 437, "lon": 24. 753, "radius_km": 50}
}
Compacto automático:
json
{ "prefix": "evo", "field": "brand_suggest", "limit": 8 }
18) Pattern UX
Chips de filtros ativos + redefinir tudo.
Resultados em branco: mostrar «experimente...» (sinônimos, remover filtro).
«Dicas a zero»: consultas populares/categorias.
Paginação com cursor (botão «Mais») e scroll infinito; um indicador fixo dos filtros aplicados.
Os botões individuais «levar em conta as falhas», «correspondência exata da frase».
19) Erros frequentes e anti-pattern
Não há tee-breaker na triagem → duplicação/salto.
As facetas não incluem filtros ativos → counts «falsos».
Aplicar filtros de acesso após classificação.
Misture as diferentes línguas com um único analisador.
Paginação profunda OFFSET/LIMIT em vez do cursor seek.
Fuzzy ilimitado → explosão por latência.
20) Checlist de implementação
1. Defina os campos e seus tipos, e atribua analisadores per-local.
2. Projete o índice inverso + (opz.) ANNN vetorial.
3. Implemente o parser de solicitação e filtros de acesso seguros (pré-filter).
4. Configure o BM25 e os bustos de campo; Ligue as facetas.
5. Digite os cursores (opaque, HMAC, TTL) e k-way merge por chard.
6. Adicione um composto automático, highlights, telas seguras.
7. Métricas: latência, NDCG @ k, CTR; L1/L2 em dinheiro.
8. A/B-frame de sintonia de relevância.
9. Documente SLA: atraso NRT, limites 'limit', garantia de consistência.
10. O plano de migração é uma versão do índice, dicionários e analisadores.
Uma camada bem projetada de filtragem e busca por texto completo não é apenas um índice rápido, mas também um contrato de protocolo claro com cursores, segurança, X previsível e relevância mensurável. Esta abordagem é dimensionada entre milhares e bilhões de documentos e suporta tanto a busca vocabulária clássica como os cenários híbridos modernos classificados neurosseticamente.