DOCUMENTACIÓN

Búsqueda vectorial

Cada proyecto de Espobase incluye pgvector. Guarda embeddings junto a tus datos, indéxalos y encuentra las filas más parecidas: para búsqueda semántica, recomendaciones o para responder preguntas sobre tu propio contenido.

← Toda la documentación

Cómo funciona

  • Un embedding es una lista de números que describe el significado de un texto o una imagen. Tu app lo obtiene de su proveedor de IA (por ejemplo, text-embedding-3-small de OpenAI, 1536 números). Espobase guarda y busca embeddings; no los crea.
  • Una columna vector(1536) guarda un embedding por fila. Los significados parecidos tienen una distancia pequeña, así que las filas más cercanas son las mejores coincidencias.
  • pgvector ya está configurado en cada proyecto: no hay extensiones que instalar ni ajustes. Funciona en el Editor SQL, el Editor de tablas (tipo de columna vector) y el creador con IA.

1. Crea una tabla

En el Editor SQL de tu proyecto:

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);

O pídeselo al creador con IA, por ejemplo: “una tabla de documentos con un embedding para búsqueda semántica”. Propone la columna vector y el índice de similitud para que los revises.

2. Agrega una función de búsqueda

Una búsqueda por similitud es una pequeña función SQL. La creas una vez y tu app la llama a través de la 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
$$;

La función se ejecuta como el usuario que la llama, así que se aplica la seguridad a nivel de fila: un usuario que inició sesión solo encuentra las filas que sus políticas permiten.

3. Guarda y busca desde tu 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,
});

Los vectores viajan como texto, por ejemplo [0.12,-0.03,…]. Si usas la API REST directamente, llama a POST /rest/v1/rpc/match_documents con el mismo cuerpo JSON.

Para tener en cuenta

  • Distancias: <=> coseno, <-> euclidiana (L2), <#> producto interno negativo. Usa la clase de operador del índice que corresponda a tus consultas (vector_cosine_ops, vector_l2_ops, vector_ip_ops).
  • Los índices HNSW admiten hasta 2000 dimensiones.
  • Crear un índice sobre muchas filas existentes toma un tiempo. Crea el índice primero, o crea los índices grandes mediante una conexión directa a la base de datos.
  • Los embeddings cuentan para el almacenamiento de base de datos de tu plan (1536 dimensiones ≈ 6 KB por fila).