Ricerca vettoriale
Ogni progetto Espobase include pgvector. Salva embedding accanto ai tuoi dati, indicizzali e trova le righe più simili: per ricerca semantica, raccomandazioni o per rispondere a domande sui tuoi contenuti.
Come funziona
- Un embedding è una lista di numeri che descrive il significato di un testo o di un'immagine. La tua app lo ottiene dal suo provider AI (ad esempio text-embedding-3-small di OpenAI, 1536 numeri). Espobase salva e cerca gli embedding; non li crea.
- Una colonna
vector(1536)contiene un embedding per riga. Significati simili hanno una distanza piccola, quindi le righe più vicine sono le corrispondenze migliori. - pgvector è già configurato in ogni progetto: nessuna estensione da installare, nessuna impostazione. Funziona nell'Editor SQL, nell'Editor tabelle (tipo di colonna
vector) e nel builder AI.
1. Crea una tabella
Nell'Editor SQL del tuo progetto:
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);
Oppure chiedilo al builder AI, ad esempio: “una tabella documents con un embedding per la ricerca semantica”. Propone la colonna vector e l'indice di similarità da farti rivedere.
2. Aggiungi una funzione di ricerca
Una ricerca per similarità è una piccola funzione SQL. La crei una volta; la tua app la chiama tramite l'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 funzione viene eseguita come l'utente che la chiama, quindi si applica la sicurezza a livello di riga: un utente che ha effettuato l'accesso trova solo le righe consentite dalle sue policy.
3. Salva e cerca dalla tua 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,
});I vettori viaggiano come testo, ad esempio [0.12,-0.03,…]. Se usi direttamente l'API REST, chiama POST /rest/v1/rpc/match_documents con lo stesso corpo JSON.
Buono a sapersi
- Distanze:
<=>coseno,<->euclidea (L2),<#>prodotto scalare negativo. Usa la classe di operatori dell'indice adatta alle tue query (vector_cosine_ops,vector_l2_ops,vector_ip_ops). - Gli indici HNSW supportano fino a 2.000 dimensioni.
- Costruire un indice su molte righe esistenti richiede tempo. Crea prima l'indice, oppure costruisci quelli grandi tramite una connessione diretta al database.
- Gli embedding contano per lo spazio database del tuo piano (1536 dimensioni ≈ 6 KB per riga).