Voltar ao Blog
    Backend
    Banco de Dados

    Busca textual no PostgreSQL: relevância e índice GIN na prática

    Implemente busca textual em português com tsvector, websearch_to_tsquery e índice GIN, entendendo limites e custos.

    Publicado em ·5 min de leitura·por Bernardo Gomes

    Para um catálogo pequeno ou médio que já usa PostgreSQL, busca textual nativa pode resolver consultas por palavras sem adicionar outro serviço. Ela transforma documentos em lexemas e consultas em expressões de busca. Não é equivalente a busca vetorial semântica, nem oferece automaticamente tolerância a erros de digitação.

    Um índice coerente com a consulta

    Neste exemplo, artigos têm título e corpo, ambos opcionais. Usamos a configuração portuguese explicitamente no índice e na consulta; expressões diferentes podem impedir o uso do índice. Crie o índice em uma migração apropriada ao volume da tabela e avalie o impacto de escrita.

    sql
    CREATE INDEX artigos_busca_gin ON artigos USING GIN (
      to_tsvector('portuguese', coalesce(titulo, '') || ' ' || coalesce(corpo, ''))
    );
    
    -- $1 é um parâmetro vinculado pela aplicação, não interpolação de SQL.
    WITH busca AS (SELECT websearch_to_tsquery('portuguese', $1) AS q)
    SELECT a.id, a.titulo,
           ts_rank(to_tsvector('portuguese', coalesce(a.titulo, '') || ' ' || coalesce(a.corpo, '')), busca.q) AS relevancia
    FROM artigos AS a CROSS JOIN busca
    WHERE to_tsvector('portuguese', coalesce(a.titulo, '') || ' ' || coalesce(a.corpo, '')) @@ busca.q
    ORDER BY relevancia DESC, a.id
    LIMIT 20;

    websearch_to_tsquery aceita uma sintaxe semelhante à de buscas na web; ts_rank calcula uma pontuação lexical. O GIN acelera o filtro de correspondência, mas a ordenação por relevância ainda tem custo sobre os candidatos. Limite o tamanho da consulta e aplique filtros de autorização antes de devolver resultados.

    Meça antes de adicionar complexidade

    • Teste com dados representativos e EXPLAIN (ANALYZE, BUFFERS), inclusive termos muito comuns e consultas vazias.
    • Avalie stemming, palavras ignoradas e acentos com o vocabulário real do produto; não prometa correção ortográfica.
    • Para coleções grandes, considere armazenar o tsvector e atribuir pesos ao título e ao corpo; mantenha o vetor atualizado.
    • Respeite isolamento entre usuários ou organizações na própria consulta e nos índices adequados ao acesso.
    • Se precisar de similaridade semântica, autocomplete ou tolerância a erros, avalie soluções específicas e compare qualidade e custo com dados reais.
    💡

    Um índice não substitui um conjunto de consultas de referência. Meça relevância, latência e custo de atualização antes de decidir se a busca nativa é suficiente.

    Fontes