Vektorsuche
Jedes Espobase-Projekt enthält pgvector. Speichere Embeddings neben deinen Daten, indexiere sie und finde die ähnlichsten Zeilen: für semantische Suche, Empfehlungen oder Antworten auf Fragen zu deinen eigenen Inhalten.
So funktioniert es
- Ein Embedding ist eine Liste von Zahlen, die die Bedeutung eines Texts oder Bildes beschreibt. Deine App bekommt es von ihrem KI-Anbieter (zum Beispiel text-embedding-3-small von OpenAI, 1536 Zahlen). Espobase speichert und durchsucht Embeddings; es erzeugt sie nicht.
- Eine Spalte
vector(1536)enthält ein Embedding pro Zeile. Ähnliche Bedeutungen haben einen kleinen Abstand, die nächstgelegenen Zeilen sind also die besten Treffer. - pgvector ist in jedem Projekt bereits eingerichtet: keine Erweiterung zu installieren, keine Einstellungen. Es funktioniert im SQL-Editor, im Tabelleneditor (Spaltentyp
vector) und im KI-Builder.
1. Tabelle anlegen
Im SQL-Editor deines Projekts:
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);
Oder frag den KI-Builder, zum Beispiel: „eine Tabelle documents mit einem Embedding für semantische Suche“. Er schlägt dir die Vektorspalte und den Ähnlichkeitsindex zur Prüfung vor.
2. Suchfunktion hinzufügen
Eine Ähnlichkeitssuche ist eine kleine SQL-Funktion. Du legst sie einmal an; deine App ruft sie über die REST API auf.
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 $$;
Die Funktion läuft als der aufrufende Nutzer, daher gilt die Row Level Security: Ein angemeldeter Nutzer findet nur die Zeilen, die seine Richtlinien erlauben.
3. Aus deiner App speichern und suchen
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,
});Vektoren werden als Text übertragen, etwa [0.12,-0.03,…]. Mit der REST API direkt rufst du POST /rest/v1/rpc/match_documents mit demselben JSON-Body auf.
Gut zu wissen
- Abstände:
<=>Kosinus,<->euklidisch (L2),<#>negatives Skalarprodukt. Verwende die Operatorklasse des Index, die zu deinen Abfragen passt (vector_cosine_ops,vector_l2_ops,vector_ip_ops). - HNSW-Indizes unterstützen bis zu 2.000 Dimensionen.
- Einen Index über viele vorhandene Zeilen aufzubauen dauert eine Weile. Leg den Index zuerst an oder baue große Indizes über eine direkte Datenbankverbindung auf.
- Embeddings zählen zum Datenbankspeicher deines Tarifs (1536 Dimensionen ≈ 6 KB pro Zeile).