DOCUMENTATION

Recherche vectorielle

Chaque projet Espobase inclut pgvector. Stockez des embeddings à côté de vos données, indexez-les et trouvez les lignes les plus proches : pour la recherche sémantique, les recommandations ou pour répondre à des questions sur votre propre contenu.

← Toute la documentation

Comment ça marche

  • Un embedding est une liste de nombres qui décrit le sens d'un texte ou d'une image. Votre app l'obtient auprès de son fournisseur d'IA (par exemple text-embedding-3-small d'OpenAI, 1536 nombres). Espobase stocke et recherche les embeddings ; il ne les crée pas.
  • Une colonne vector(1536) contient un embedding par ligne. Des sens proches ont une petite distance : les lignes les plus proches sont donc les meilleures correspondances.
  • pgvector est déjà configuré dans chaque projet : aucune extension à installer, aucun réglage. Il fonctionne dans l'Éditeur SQL, l'Éditeur de tables (type de colonne vector) et le générateur IA.

1. Créez une table

Dans l'Éditeur SQL de votre projet :

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 demandez-le au générateur IA, par exemple : « une table de documents avec un embedding pour la recherche sémantique ». Il propose la colonne vector et l'index de similarité pour que vous les relisiez.

2. Ajoutez une fonction de recherche

Une recherche par similarité est une petite fonction SQL. Vous la créez une fois ; votre app l'appelle via 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 fonction s'exécute en tant qu'utilisateur appelant, donc la sécurité au niveau des lignes s'applique : un utilisateur connecté ne trouve que les lignes que ses politiques autorisent.

3. Stockez et recherchez depuis votre 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,
});

Les vecteurs circulent sous forme de texte, par exemple [0.12,-0.03,…]. Avec l'API REST directement, appelez POST /rest/v1/rpc/match_documents avec le même corps JSON.

Bon à savoir

  • Distances : <=> cosinus, <-> euclidienne (L2), <#> produit scalaire négatif. Utilisez la classe d'opérateurs d'index qui correspond à vos requêtes (vector_cosine_ops, vector_l2_ops, vector_ip_ops).
  • Les index HNSW prennent en charge jusqu'à 2 000 dimensions.
  • Construire un index sur de nombreuses lignes existantes prend du temps. Créez d'abord l'index, ou construisez les gros index via une connexion directe à la base de données.
  • Les embeddings comptent dans le stockage de base de données de votre offre (1536 dimensions ≈ 6 Ko par ligne).