Banco de Dados Nathan Geeksman

Postgres full-text search: substitua o Elasticsearch em casos simples

Postgres full-text search: substitua o Elasticsearch em casos simples

Postgres full-text search: substitua o Elasticsearch em casos simples

Introdução

O desenvolvimento de aplicativos escaláveis e de alta performance é um desafio constante no contexto atual. A integração de funcionalidades de busca avançadas, como a capacidade de realizar pesquisas full-text com precisão, é uma das principais demandas enfrentadas pelos desenvolvedores.

Neste cenário, o Elasticsearch tem sido frequentemente escolhido como solução para esses problemas. No entanto, o uso do Elasticsearch pode ser complexo e caro, especialmente em casos simples onde não se justificam os custos associados à manutenção de um sistema adicional.

Aqui, exploraremos a funcionalidade de busca full-text no PostgreSQL, uma base de dados relacional robusta e escalável. Essa funcionalidade permite realizar pesquisas complexas diretamente na base de dados sem a necessidade de integrações com outros serviços ou ferramentas.

Neste artigo, vamos aprender a substituir o Elasticsearch em casos simples por meio da utilização eficaz das funcionalidades de busca full-text no PostgreSQL.

O que é e por que importa

A busca full-text é uma funcionalidade de pesquisa avançada que permite realizar pesquisas em dados texto brutos, como campos de texto, notas, etc. Ela usa técnicas de Processamento de Linguagem Natural (PLN) para analisar a estrutura e o significado das palavras, permitindo encontrar matches precisos mesmo quando as palavras-chave não estão presentes na base de dados exatamente como inseridas.

Full-text search é uma técnica que indexa os campos texto da sua base de dados em um índice especializado, permitindo realizar pesquisas eficientes e escaláveis. No contexto do PostgreSQL, a busca full-text é implementada através das funções pg_trgm, gin e gist, que fornecem uma forma eficiente e flexível de realizar buscas full-text.

A motivação para utilizar a busca full-text no PostgreSQL reside na necessidade de realizar pesquisas complexas em dados texto brutos, como nomes de produtos, descrições de serviços, etc. Ela resolve problemas como encontrar resultados com base em palavras-chave semelhantes ou sinônimos, realizar buscas por expressões regulares e fornecer resultados ordenados pela relevância.

A busca full-text no PostgreSQL é uma solução escalável e performática para casos simples, onde a complexidade e os custos associados ao uso do Elasticsearch não são justificáveis. Além disso, ela permite uma integração mais direta e transparente com a base de dados, reduzindo assim a necessidade de desenvolver camadas adicionais de software para lidar com as buscas avançadas.

Como funciona na prática

A busca full-text no PostgreSQL utiliza um processo chamado de Indexação para criar um índice dos campos texto da base de dados.

  • Primeiramente, os dados são analisados e transformados em uma representação interna, que é usada pelo índice.
  • O índice é então criado a partir dessas representações internas, o que permite uma busca rápida e eficiente nos campos texto.
  • Ao realizar uma consulta de busca full-text, o PostgreSQL utiliza o índice para comparar as palavras-chave com os dados armazenados no índice.
  • A comparação é feita usando técnicas de similaridade entre as palavras-chave e os dados do índice, como por exemplo a similaridade lexicográfica ou a similaridade fonética.
  • O resultado da busca é então ordenado pela relevância, o que significa que os resultados mais relevantes são mostrados primeiro.

O processo de indexação pode ser realizado de forma assíncrona, o que significa que ele não interfere com as operações normais da base de dados. Além disso, o índice é atualizado automaticamente sempre que os dados mudam, garantindo que a busca full-text esteja sempre up-to-date.

A busca full-text no PostgreSQL também suporta várias opções de personalização, como por exemplo:

  • Ponderação: permite que sejam atribuídas ponderações às diferentes palavras-chave para influenciar na relevância dos resultados.
  • Filtros: permite que sejam aplicados filtros aos resultados da busca full-text, como por exemplo filtrar apenas pelos resultados mais recentes.

Essas opções de personalização permitem que a busca full-text seja adaptada às necessidades específicas do uso e das preferências dos usuários.

Exemplo real

Um exemplo prático de como utilizar a busca full-text no PostgreSQL é um sistema de gerenciamento de conhecimento interno em uma empresa.

Suponha que você está trabalhando em uma grande empresa e precisamos criar um sistema para armazenar e buscar informações sobre os funcionários, incluindo seu currículo e experiência profissional. O objetivo é permitir que os colaboradores busquem por pessoas com habilidades específicas ou experiência em áreas determinadas.

Aqui está um exemplo de como pode ser estruturado o banco de dados:

-- Criar tabela para armazenar informações sobre funcionários
CREATE TABLE funcionarios (
    id serial PRIMARY KEY,
    nome VARCHAR(255) NOT NULL,
    email VARCHAR(255) NOT NULL,
    descricao TEXT NOT NULL
);

-- Criar índice full-text na coluna "descricao"
CREATE INDEX idx_funcionarios_descricao ON funcionarios USING GIST (to_tsvector("nome" || ' ' || descricao));

-- Inserir alguns dados de exemplo
INSERT INTO funcionarios (nome, email, descricao)
VALUES 
    ('João Silva', 'joao.silva@example.com', 'Desenvolvedor Full-stack com experiência em Python e Java. Trabalhou em projetos de desenvolvimento web e mobil'),
    ('Maria Oliveira', 'maria.oliveira@example.com', 'Engenheira de software com habilidades em análise de dados e Machine Learning. Atua em projetos de inteligência artificial'),
    ('Carlos Santos', 'carlos.santos@example.com', 'Designer UI/UX com experiência em design de interfaces e experiência em projetos de desenvolvimento web');

Nesse exemplo, criamos uma tabela funcionarios para armazenar as informações sobre os funcionários. Em seguida, criamos um índice full-text na coluna descricao, que contém a descrição curta do currículo e experiência profissional de cada funcionário.

Aqui está como você pode realizar uma busca full-text nos dados:

-- Buscar por pessoas com habilidades em Python ou Java
SELECT *
FROM funcionarios
WHERE to_tsvector("nome" || ' ' || descricao) @@ to_tsquery('python | java');

-- Buscar por pessoas com experiência em desenvolvimento web
SELECT *
FROM funcionarios
WHERE to_tsvector("nome" || ' ' || descricao) @@ to_tsquery('desenvolvimento web');

Nesse exemplo, utilizamos a função to_tsvector() para criar um vetor de palavras-chave da coluna descricao e a função to_tsquery() para realizar a busca full-text. A expressão @@ é utilizada para comparar o vetor de palavras-chave com a consulta.

Essa é apenas uma visão geral do que pode ser feito utilizando a busca full-text no PostgreSQL. Existem muitas outras opções e técnicas que podem ser exploradas, como ponderação, filtros e personalização da busca, conforme mencionado anteriormente.

Boas práticas

Utilize a forma correta de criar índices full-text

  • Certifique-se de que as colunas que contêm texto estejam configuradas para suportar busca full-text.
  • Use a função CREATE INDEX com o tipo de índice GIN (Generalized Inverted Index) ou GIST (Generalized Search Tree), dependendo do uso específico.

Utilize consultas eficientes

  • Evite consultar todas as colunas da tabela, apenas os campos necessários.
  • Use a função to_tsvector() para criar o vetor de palavras-chave somente quando necessário e armazene-o em uma variável ou campo.

Armadilhas comuns

Difícil manutenção do índice

  • Ao adicionar novas colunas ao índice full-text, certifique-se que a atualização seja eficiente e não impacte negativamente o desempenho da consulta.
  • Utilize a função REINDEX para recalcular o índice após alterações significativas.

Desempenho de consultas

  • Ao utilizar a busca full-text, certifique-se que as consultas sejam indexadas corretamente e não estejam impactando negativamente o desempenho.
  • Utilize a função EXPLAIN para analisar e otimizar as consultas.

Conclusão

O uso da busca full-text no PostgreSQL pode ser uma solução eficaz e escalável para casos simples de pesquisa em texto, especialmente quando comparado ao Elasticsearch.

Para aproveitar ao máximo essa funcionalidade, é crucial entender como criar índices full-text corretamente, evitar consultas ineficientes e manter a atualização do índice sem impactar negativamente o desempenho.

Um próximo passo pode ser explorar como aplicar ponderação, filtros e personalização da busca para aumentar a precisão e relevância das resultados de pesquisa. Além disso, entender as possibilidades de integração com outros recursos do PostgreSQL, como a capacidade de criar índices full-text em colunas múltiplas, pode ser uma área interessante para explorar.

Aumentar sua familiaridade com o uso da busca full-text no PostgreSQL também pode ajudar a identificar oportunidades para melhorar o desempenho e escalabilidade de sistemas que dependem de consultas complexas.

Referências

  • PostgreSQL. "PostgreSQL Full-text Search". Disponível em: <https://www.postgresql.org/docs/current/textsearch.html>. Acesso: 2024.
  • PostgreSQL. "REINDEX". Disponível em: <https://www.postgresql.org/docs/current/sql-reindex.html>. Acesso: 2024.
  • PostgreSQL. "EXPLAIN" . Disponível em: <https://www.postgresql.org/docs/current/sql-explain.html>. Acesso: 2024.
  • IBM Knowledge Center. "Search for text in a column". Disponível em: <https://www.ibm.com/support/knowledgecenter/en/SSJSPF_12.0.3/com.ibm.as400.doc/base/ds_sql_search_for_text.htm>. Acesso: 2024.
  • PostgreSQL. "CREATE INDEX". Disponível em: <https://www.postgresql.org/docs/current/sql-createindex.html>. Acesso: 2024