Full-Text Search no MySQL
MATCH ... AGAINST na prática
Sintaxe, modos NATURAL LANGUAGE e BOOLEAN, e consultas compostas.
Nesta aula você vai
- Escrever consultas MATCH ... AGAINST nos modos NATURAL LANGUAGE e BOOLEAN
- Combinar full-text com filtros estruturados (categoria, status)
- Usar o score do MATCH na ordenação da API de busca
MATCH ... AGAINST na prática
Objetivos
Nesta aula você vai:
- Dominar a sintaxe
MATCH (cols) AGAINST ('...' IN ... MODE) - Escolher entre linguagem natural e modo booleano
- Montar consultas compostas para o catálogo OficinaHub e para tickets
Introdução
Com o índice FULLTEXT criado, a porta de entrada é MATCH ... AGAINST. Essa cláusula não é um LIKE disfarçado: ela passa pelo analisador, consulta postings e devolve score. O modo altera a semântica da consulta — e, com ela, a UX.
Conteúdo
Modo NATURAL LANGUAGE
Ideal para caixas de busca “digite livremente”. O motor interpreta a frase, aplica stopwords e ranqueia.
SELECT id, nome, sku,
MATCH(nome, descricao, tags_texto)
AGAINST ('serra circular madeira' IN NATURAL LANGUAGE MODE) AS score
FROM produtos
WHERE MATCH(nome, descricao, tags_texto)
AGAINST ('serra circular madeira' IN NATURAL LANGUAGE MODE)
ORDER BY score DESC
LIMIT 20;
Observações:
- A mesma expressão
MATCH ... AGAINSTnoSELECTe noWHEREpermite projetar o score - Resultados com score muito baixo podem ser filtrados por limiar na aplicação, se fizer sentido
Modo BOOLEAN
Dá controle fino: obrigatoriedade, exclusão, prefixo, frase.
SELECT id, nome, score
FROM (
SELECT id, nome,
MATCH(nome, descricao, tags_texto)
AGAINST ('+serra +circular -plastico' IN BOOLEAN MODE) AS score
FROM produtos
WHERE MATCH(nome, descricao, tags_texto)
AGAINST ('+serra +circular -plastico' IN BOOLEAN MODE)
) AS t
WHERE score > 0
ORDER BY score DESC
LIMIT 20;
| Operador | Significado | Exemplo |
|---|---|---|
+termo |
Obrigatório | +torquimetro |
-termo |
Excluir | -manual |
termo* |
Prefixo | parafus* |
"a b" |
Frase | "chave catraca" |
> < |
Ajustar peso relativo | >digital <analogico |
-- Prefixo para famílias de produto
SELECT id, nome
FROM produtos
WHERE MATCH(nome, descricao, tags_texto)
AGAINST ('+furadeira +impacto*' IN BOOLEAN MODE);
Consultas compostas com filtros estruturados
Full-text resolve relevância textual; colunas estruturadas resolvem facetas.
SELECT p.id, p.nome, p.categoria,
MATCH(p.nome, p.descricao, p.tags_texto)
AGAINST ('torquimetro digital' IN NATURAL LANGUAGE MODE) AS score
FROM produtos AS p
WHERE MATCH(p.nome, p.descricao, p.tags_texto)
AGAINST ('torquimetro digital' IN NATURAL LANGUAGE MODE)
AND p.categoria = 'medicao'
AND p.nome NOT LIKE '%/%' -- exemplo de regra de negócio residual
ORDER BY score DESC
LIMIT 20;
No TicketFlow (MySQL):
SELECT id, assunto, status,
MATCH(assunto, corpo) AGAINST ('cobrança duplicada' IN NATURAL LANGUAGE MODE) AS score
FROM tickets
WHERE MATCH(assunto, corpo) AGAINST ('cobrança duplicada' IN NATURAL LANGUAGE MODE)
AND status IN ('aberto', 'em_andamento')
AND fila = 'financeiro'
ORDER BY score DESC, aberto_em DESC
LIMIT 25;
Query expansion (opcional)
WITH QUERY EXPANSION pode ampliar a busca com termos de documentos bem ranqueados na primeira passagem. Útil em corpora específicos; teste antes — pode trazer ruído.
SELECT id, nome
FROM produtos
WHERE MATCH(nome, descricao)
AGAINST ('multímetro' WITH QUERY EXPANSION);
Problema comum e solução
Problema: misturar modo booleano na expectativa de “frase em linguagem natural” e obter zero resultados por exigir + demais, ou o contrário: linguagem natural quando o produto precisa de exclusões explícitas.
Solução: linguagem natural para busca aberta de usuário final; booleano para filtros avançados, painéis internos e APIs que montam operadores com segurança (escape/validação). Nunca concatene input cru em BOOLEAN MODE sem sanitizar operadores.
Como analisar
EXPLAIN
SELECT id
FROM produtos
WHERE MATCH(nome, descricao, tags_texto)
AGAINST ('+serra +circular' IN BOOLEAN MODE)
LIMIT 20;
-- Sanity check: score e amostra
SELECT id, nome,
MATCH(nome, descricao, tags_texto)
AGAINST ('serra circular' IN NATURAL LANGUAGE MODE) AS score
FROM produtos
WHERE MATCH(nome, descricao, tags_texto)
AGAINST ('serra circular' IN NATURAL LANGUAGE MODE)
ORDER BY score DESC
LIMIT 5;
Valide manualmente se o top-5 “parece certo” para o time de catálogo.
Resumo
NATURAL LANGUAGEranqueia frases livres;BOOLEANoferece operadores precisos- Projete o score e ordene por ele
- Combine
MATCHcom filtros estruturados (categoria, status, fila) - Trate input de BOOLEAN MODE com cuidado; prefira APIs que montam a query de forma segura