Full-Text Search no MySQL

MATCH ... AGAINST na prática

Sintaxe, modos NATURAL LANGUAGE e BOOLEAN, e consultas compostas.

Intermediário 42 min 34 pontos Leitura 0%

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 ... AGAINST no SELECT e no WHERE permite 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 LANGUAGE ranqueia frases livres; BOOLEAN oferece operadores precisos
  • Projete o score e ordene por ele
  • Combine MATCH com filtros estruturados (categoria, status, fila)
  • Trate input de BOOLEAN MODE com cuidado; prefira APIs que montam a query de forma segura