Fundamentos de Full-Text Search

Tokenização e stopwords

Como o texto vira tokens e por que preposições e artigos são descartados.

Intermediário 40 min 30 pontos Leitura 0%

Nesta aula você vai

  • Descrever as etapas de tokenização em um motor full-text
  • Explicar o papel das stopwords e o risco de removê-las demais
  • Aplicar to_tsvector e equivalentes mentais ao MySQL FULLTEXT

Tokenização e stopwords

Objetivos

Nesta aula você vai:

  • Percorrer o pipeline que transforma texto bruto em tokens indexáveis
  • Entender por que artigos e preposições costumam ser descartados
  • Experimentar tokenização em português com exemplos de catálogo e tickets

Introdução

Full-text search começa antes do índice: começa na análise léxica. Sem essa etapa, o motor armazenaria strings inteiras e voltaria ao mundo do LIKE. Tokenizar é decidir onde uma palavra começa e termina, como normalizar acentos/caixa e o que jogar fora porque não discrimina documentos.

Voltemos à Estante Norte. A sinopse “O guia prático de redes neurais para o time de dados” contém palavras de conteúdo (guia, prático, redes, neurais, time, dados) e palavras funcionais (o, de, para). Se indexássemos tudo com o mesmo peso, consultas como de inundariam o índice e o ranking perderia sinal.

Conteúdo

Pipeline típico

  1. Segmentação: cortar o texto em candidatos a token (espaços, pontuação)
  2. Normalização: minúsculas, às vezes remoção de acentos conforme configuração
  3. Stopwords: remover termos muito frequentes e pouco discriminativos
  4. Stemming / lemmatização (opcional): reduzir flexões a um radical ou lema
  5. Emissão: gravar tokens (com posições) no índice invertido
-- PostgreSQL: ver o resultado da análise
SELECT to_tsvector(
  'portuguese',
  'O guia prático de redes neurais para o time de dados'
);

Resultado ilustrativo:

'dad':9 'gui':2 'neural':6 'pratic':3 'red':5 'tim':8
Etapa Efeito no exemplo
Segmentação Separa palavras e ignora pontuação residual
Stopwords portuguese Remove o, de, para
Stemming práticopratic, redesred, etc.

Stopwords: sinal versus ruído

Stopwords existem porque termos ubíquos aparecem em quase todos os documentos. Indexá-los:

  • Infla o índice (postings longuíssimos)
  • Empobrece o ranking (tudo “casa” com de)
  • Aumenta o custo de consulta composta

Há exceções. Em catálogos de código ou SKU, a, in, or podem ser significativos. Em português literário, remover agressivamente demais pode prejudicar títulos curtos. A lista padrão do idioma é um bom ponto de partida; customizar exige evidência de busca real.

-- TicketFlow: corpo de ticket com muito “ruído” funcional
SELECT to_tsvector(
  'portuguese',
  'O cliente relatou que o gateway de pagamento retornou timeout após a confirmação'
);

Termos de conteúdo (cliente, gateway, pagamento, retornou, timeout, confirmação) tendem a permanecer; artigos e preposições caem.

MySQL: a intuição correspondente

No MySQL FULLTEXT, a análise também tokeniza e aplica stopwords (lista do servidor / plugin). O modo NATURAL LANGUAGE e o BOOLEAN operam sobre tokens, não sobre substrings:

-- Conceito: MATCH usa o analisador FULLTEXT da tabela
SELECT id, titulo
FROM obras
WHERE MATCH(titulo, sinopse) AGAINST ('redes neurais' IN NATURAL LANGUAGE MODE);

Consultas com termos só de stopword podem retornar vazio ou comportamento degenerado — outro motivo para educar o produto a não buscar apenas de ou para.

Tokens e posição

Muitos motores guardam a posição do token no documento. Isso permite:

  • Frases ("rede neural" como sequência)
  • Ranking que favorece termos no início
  • Consultas de proximidade

Sem posições, sobra apenas presença/ausência do termo — útil, mas mais pobre.

Problema comum e solução

Problema: a busca “não acha” títulos compostos só de stopwords ou termos curtos demais (abaixo do ft_min_token_size / configuração equivalente).

Solução: documentar limites do analisador para o time de produto; ajustar listas de stopword e tamanhos mínimos com cuidado; para códigos curtos, manter um campo literal indexado à parte (B-tree / LIKE 'SKU%'), sem exigir do FTS o que ele não foi projetado para resolver.

Como analisar

Sempre inspecione o que o analisador realmente emite:

-- PostgreSQL
SELECT * FROM ts_debug('portuguese', 'ferramentas elétricas para madeira úmida');

-- Comparar consulta e documento
SELECT plainto_tsquery('portuguese', 'ferramenta elétrica madeira');
-- MySQL: valide com consultas controladas e EXPLAIN;
-- confira ft_min_token_size e a stopword list do servidor
SHOW VARIABLES LIKE 'ft_min_token_size';

Se o token que o usuário digita não sobrevive à análise, nenhum índice invertido o encontrará.

Resumo

  • Tokenização transforma texto em unidades indexáveis; stopwords removem ruído frequente
  • Em português, artigos e preposições costumam sair — e isso é desejável na maioria dos catálogos
  • MySQL FULLTEXT e PostgreSQL tsvector compartilham a mesma ideia analítica
  • Debugar busca começa por ver os tokens, não por adicionar mais OR no SQL