Voltar ao Blog
Jul 21, 2026
Engineering
Equipe Editorial Greta

Funcionalidade de Busca em um App Construído com IA: Quando o Postgres É Suficiente

A maioria das barras de busca começa como uma consulta ILIKE e silenciosamente vira um problema de performance. Veja quando a busca full-text do Postgres é suficiente e quando é hora de partir para Meilisearch, Typesense ou Algolia.

Funcionalidade de Busca em um App Construído com IA: Quando o Postgres É Suficiente

Funcionalidade de Busca em um App Construído com IA: Quando o Postgres É Suficiente

Resposta rápida

A maioria dos apps não precisa de um motor de busca dedicado — a busca full-text do Postgres com um índice GIN dá conta de filtragem, ranqueamento e uma tolerância razoável a erros de digitação para bases com até algumas centenas de milhares de linhas. Você só precisa de Meilisearch, Typesense ou Algolia quando quer resultados instantâneos a cada tecla digitada, correspondência fuzzy de verdade, ou busca em milhões de linhas com latência abaixo de 50ms. Comece pelo banco de dados que você já tem.

O erro que mais custa tempo depois

Alguém adiciona uma barra de busca, conecta com WHERE nome ILIKE '%busca%', publica e segue em frente. Funciona na demo porque a demo tem quarenta linhas. Seis semanas depois já são sessenta mil linhas, essa consulta faz uma varredura sequencial a cada tecla digitada, e a "busca" virou o motivo do painel parecer lento.

ILIKE não é busca. É correspondência de texto que funciona enquanto ninguém presta muita atenção. Não ranqueia resultados, não entende "invoise" quando alguém quis dizer "invoice", e fica linearmente mais lenta conforme a tabela cresce, porque não existe índice de verdade por trás dela.

Já vi esse mesmo chamado de suporte chegar três vezes: "a busca parece quebrada", quando o problema nunca foi a lógica da consulta — era que ninguém tinha indexado nada, e o banco estava lendo cada linha a cada tecla digitada.

O que uma busca de verdade precisa fazer

Três coisas, mais ou menos na ordem em que as pessoas costumam pular: ranquear resultados por relevância em vez de só bater ou não bater, lidar com várias palavras em qualquer ordem, e continuar rápida conforme a tabela cresce além do que cabe numa varredura sequencial confortável. Tolerância a erro de digitação é bom ter. Também é a primeira coisa que as pessoas buscam quando o problema real são os dois primeiros pontos.

A busca full-text do Postgres, e por que ela é subestimada

O Postgres tem um motor de busca de verdade embutido desde a versão 8.3, e a maioria dos times nunca chega a usar. tsvector e tsquery te dão stemming (buscar "correndo" e encontrar "correr"), ranqueamento via ts_rank, e um índice GIN que deixa tudo rápido numa escala que a maioria dos apps nunca chega a atingir.

A configuração é bem enxuta. Adicione uma coluna tsvector gerada, indexe, consulte com @@:

ALTER TABLE posts ADD COLUMN search_vector tsvector
  GENERATED ALWAYS AS (to_tsvector('portuguese', title || ' ' || body)) STORED;
CREATE INDEX posts_search_idx ON posts USING GIN (search_vector);

A partir daí, uma consulta como SELECT * FROM posts WHERE search_vector @@ plainto_tsquery('portuguese', 'construtor de app com ia') ORDER BY ts_rank(search_vector, plainto_tsquery('portuguese', 'construtor de app com ia')) DESC devolve resultados ranqueados e com stemming, e continua rápida até centenas de milhares de linhas porque o índice GIN está fazendo trabalho de verdade, não uma varredura de tabela disfarçada de busca.

O que ela não faz: perdoar erros de digitação com naturalidade, parecer instantânea a cada tecla sem esforço extra, ou buscar em várias tabelas não relacionadas numa única consulta sem você mesmo juntar os resultados depois.

Onde a busca do Postgres realmente falha

Em dois pontos previsíveis. Primeiro, tolerância a erro de digitação — o pg_trgm te leva até certo ponto com similaridade por trigramas, mas é um contorno, não a coisa de verdade que um motor dedicado já entrega pronta. Segundo, a experiência instantânea a cada tecla em escala real. Uma consulta indexada por GIN é rápida, mas conectar teclas digitadas com debounce direto no seu banco principal a cada requisição gera uma carga que você não quer ali, especialmente quando a busca já é popular o suficiente para representar uma fatia relevante do seu volume total de consultas.

Quando trazer um motor de busca dedicado

O gatilho real não é o número de linhas isoladamente — é se a busca é uma funcionalidade central do produto ou só um extra. Uma busca de chamados de suporte usada duas vezes por dia não precisa de Typesense. Um marketplace onde a busca é o produto, ou um site de documentação onde o usuário desiste se o primeiro resultado não for o certo, justifica a infraestrutura extra.

Meilisearch e Typesense são os dois que vale conhecer. Ambos são open-source, podem ser auto-hospedados ou gerenciados, e foram feitos especificamente para busca tolerante a erro de digitação, instantânea e abaixo de 50ms — a coisa que o Postgres consegue se aproximar, mas para a qual não foi desenhado. O Algolia faz o mesmo trabalho como SaaS totalmente gerenciado, com um conjunto de ferramentas de interface mais maduro e um modelo de preço por requisição que fica caro rápido em volume real.

A troca que você aceita de qualquer forma: um segundo sistema para manter sincronizado com o seu banco principal, geralmente via webhook ou um job em fila a cada criação, atualização ou exclusão. Isso não é de graça. Vale a pena exatamente quando a qualidade da busca é algo que os usuários notariam e reclamariam se fosse pior.

Uma comparação: busca do Postgres vs. um motor dedicado

PontoBusca full-text do PostgresMeilisearch / Typesense / Algolia
Custo de configuraçãoUma migração, um índiceNovo serviço, pipeline de sincronização
Tolerância a erro de digitaçãoParcial, via pg_trgmNativa, pronta pra usar
Latência em escalaBoa até ~500 mil linhasAbaixo de 50ms em milhões de linhas
Atualização dos dadosSempre ao vivo (mesmo banco)Eventualmente consistente, precisa de sincronização
Infraestrutura extraNenhumaSim — hospedada ou auto-gerenciada
Ideal paraFerramentas internas, busca típica de SaaSMarketplaces, documentação, e-commerce

Onde isso vive em um app construído com a Greta

Um app gerado pela Greta roda em Postgres por padrão, então a busca full-text costuma ser o ponto de partida certo — você não está adicionando nada, só usando o que já está ali. A coluna tsvector e o índice GIN vivem no mesmo schema que o resto, e a consulta fica numa rota de API normal, ao lado da sua outra lógica de busca de dados, não como um serviço colado por fora.

Se um projeto realmente precisar migrar para um motor dedicado mais adiante, o job de sincronização que mantém tudo atualizado é o mesmo padrão de job em segundo plano coberto em rodando jobs em segundo plano e tarefas agendadas — um job em fila a cada escrita, não uma chamada direta que deixa cada salvamento mais lento. E como as rotas de busca costumam estar entre as mais acessadas de um app, vale a pena combiná-las com os limites em camadas de rate limiting e prevenção de abuso, especialmente se os resultados de busca algum dia alimentarem algo que chama um LLM, como resumos gerados por IA dos resultados.

Perguntas frequentes

Posso simplesmente usar ILIKE num app pequeno? Para um punhado de linhas e uma ferramenta interna que ninguém depende, sem problema. No momento em que a busca vira uma funcionalidade que usuários reais tocam todo dia, migre para tsvector — custa uma migração e elimina uma categoria inteira de chamados de "por que a busca está lenta" depois.

A busca full-text do Postgres funciona em várias tabelas ao mesmo tempo? Não numa única consulta sem esforço extra. Você combina resultados de consultas separadas no código da aplicação, ou constrói uma view materializada que une os campos pesquisáveis que interessam. Dá para fazer, só não é automático como num motor de busca feito sob medida para isso.

Vale a pena pagar Algolia numa startup pequena? Geralmente não no começo. O forte do Algolia é um conjunto de interface pronto e configuração instantânea, mas o preço por busca pesa rápido assim que o tráfego fica real. Meilisearch ou Typesense entregam 90% da experiência auto-hospedados por uma fração do custo, e o Postgres leva você mais longe do que a maioria espera antes de precisar de qualquer um dos dois.

Como adicionar tolerância a erro de digitação no Postgres sem trocar de motor? Ative a extensão pg_trgm e adicione um índice de trigramas para correspondência por similaridade, junto com a sua coluna tsvector. Não é tão flexível quanto um motor de busca fuzzy dedicado, mas cobre o caso comum — uma letra trocada ou faltando — sem adicionar um novo serviço para operar.

Fechamento

Busca é uma daquelas funcionalidades em que o primeiro movimento óbvio — ILIKE num WHERE — também é o que silenciosamente vira um problema de performance que ninguém percebe até a tabela crescer dez vezes. A busca full-text do Postgres resolve isso pra grande maioria dos apps com uma migração e nenhuma infraestrutura nova. Guarde o motor de busca dedicado para o dia em que a busca em si for o produto.

Comece a construir seu app com a Greta hoje.

Fim do artigo
Voltar ao topo

Construa Algo de Verdade

Se você consegue descrever, você consegue criar.