DOCUMENTAZIONE

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.

← Tutta la documentazione

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