Busca vetorial
Todo projeto do Espobase inclui pgvector. Guarde embeddings ao lado dos seus dados, indexe-os e encontre as linhas mais parecidas: para busca semântica, recomendações ou respostas a perguntas sobre o seu próprio conteúdo.
Como funciona
- Um embedding é uma lista de números que descreve o significado de um texto ou de uma imagem. Seu app o obtém do provedor de IA dele (por exemplo, text-embedding-3-small da OpenAI, 1536 números). O Espobase guarda e pesquisa embeddings; ele não os cria.
- Uma coluna
vector(1536)guarda um embedding por linha. Significados parecidos têm uma distância pequena, então as linhas mais próximas são os melhores resultados. - O pgvector já vem configurado em todo projeto: nenhuma extensão para instalar, nenhuma configuração. Ele funciona no Editor SQL, no Editor de tabelas (tipo de coluna
vector) e no construtor com IA.
1. Crie uma tabela
No Editor SQL do seu projeto:
create table documents ( id bigint generated always as identity primary key, content text not null, embedding vector(1536) not null ); -- Fast similarity search (cosine distance) create index on documents using hnsw (embedding vector_cosine_ops); -- Who may read: row level security is on for every table create policy "Anyone can read documents" on documents for select using (true);
Ou peça ao construtor com IA, por exemplo: “uma tabela documents com um embedding para busca semântica”. Ele propõe a coluna vector e o índice de similaridade para você revisar.
2. Adicione uma função de busca
Uma busca por similaridade é uma pequena função SQL. Você a cria uma vez; seu app a chama pela API REST.
create function match_documents(query_embedding vector(1536), match_count int) returns table (id bigint, content text, similarity float) language sql stable as $$ select id, content, 1 - (embedding <=> query_embedding) as similarity from documents order by embedding <=> query_embedding limit match_count $$;
A função é executada como o usuário que a chama, então a segurança em nível de linha se aplica: um usuário conectado só encontra as linhas que as políticas dele permitem.
3. Guarde e busque a partir do seu app
import { createClient } from "@espobase/client";
const espobase = createClient(PROJECT_URL, PUBLISHABLE_KEY);
// Store: your app gets the embedding from its AI provider (1536 numbers).
await espobase.from("documents").insert({
content: "How to reset your password",
embedding: JSON.stringify(embedding),
});
// Search: the 5 most similar documents to the user's question.
const { data } = await espobase.rpc("match_documents", {
query_embedding: JSON.stringify(questionEmbedding),
match_count: 5,
});Os vetores trafegam como texto, por exemplo [0.12,-0.03,…]. Usando a API REST diretamente, chame POST /rest/v1/rpc/match_documents com o mesmo corpo JSON.
Bom saber
- Distâncias:
<=>cosseno,<->euclidiana (L2),<#>produto interno negativo. Use a classe de operadores do índice que corresponde às suas consultas (vector_cosine_ops,vector_l2_ops,vector_ip_ops). - Os índices HNSW suportam até 2.000 dimensões.
- Criar um índice sobre muitas linhas existentes leva algum tempo. Crie o índice primeiro ou crie índices grandes por uma conexão direta com o banco de dados.
- Os embeddings contam para o armazenamento de banco de dados do seu plano (1536 dimensões ≈ 6 KB por linha).