Der Rememberizer Vektor-Speicher vereinfacht den Umgang mit Vektordaten, sodass Sie sich auf die Texteingabe konzentrieren und die Leistungsfähigkeit von Vektoren für verschiedene Anwendungen wie Suche und Datenanalyse nutzen können.
Einführung
Der Rememberizer Vector Store bietet eine benutzerfreundliche Schnittstelle zur Handhabung von Vektordaten und abstrahiert dabei die Komplexität von Vektor-Embeddings. Angetrieben von PostgreSQL mit der pgvector-Erweiterung ermöglicht der Rememberizer Vector Store die direkte Arbeit mit Text. Der Dienst kümmert sich um das Chunking, die Vektorisierung und das Speichern der Textdaten, sodass Sie sich leichter auf Ihre Kernanwendungslogik konzentrieren können.
Für ein tieferes Verständnis der theoretischen Konzepte hinter Vektor-Embeddings und Vektordatenbanken siehe .
Technische Übersicht
Wie Vektor-Speicher funktionieren
Rememberizer Vektor-Speicher wandeln Text in hochdimensionale Vektor-Darstellungen (Embeddings) um, die die semantische Bedeutung erfassen. Dies ermöglicht:
Semantische Suche: Dokumente basierend auf Bedeutung und nicht nur auf Schlüsselwörtern finden
Effiziente Abrufung: Relevante Informationen schnell aus großen Datensätzen lokalisieren
Schlüsselkomponenten
Dokumentenverarbeitung: Texte werden in optimal große Abschnitte mit überlappenden Grenzen zur Kontextbewahrung aufgeteilt
Vektorisierung: Abschnitte werden mit modernsten Modellen in Einbettungen umgewandelt
Indizierung: Spezialisierte Algorithmen organisieren Vektoren für eine effiziente Ähnlichkeitssuche
Abfrageverarbeitung: Suchanfragen werden vektorisiert und mit gespeicherten Einbettungen verglichen
Architektur
Rememberizer implementiert Vektorspeicher mit:
PostgreSQL mit pgvector-Erweiterung: Für effiziente Vektorspeicherung und -suche
Sammlungsbasierte Organisation: Jeder Vektorspeicher hat seine eigene isolierte Sammlung
API-gesteuerter Zugriff: Einfache RESTful-Endpunkte für alle Operationen
Erste Schritte
Erstellen eines Vektor-Speichers
Navigieren Sie zum Abschnitt Vektor-Speicher in Ihrem Dashboard
Klicken Sie auf "Neuen Vektor-Speicher erstellen":
Ein Formular wird angezeigt, das Sie auffordert, Details einzugeben.
Füllen Sie die Details aus:
Name: Geben Sie einen eindeutigen Namen für Ihren Vektor-Speicher an.
Beschreibung: Schreiben Sie eine kurze Beschreibung des Vektor-Speichers.
Einbettungsmodell: Wählen Sie das Modell aus, das Text in Vektoren umwandelt.
Indexierungsalgorithmus: Wählen Sie aus, wie Vektoren für die Suche organisiert werden.
Suchmetrik: Definieren Sie, wie die Ähnlichkeit zwischen Vektoren berechnet wird.
Vektor-Dimension: Die Größe der Vektor-Einbettungen (typischerweise 768-1536).
Reichen Sie das Formular ein:
Klicken Sie auf die Schaltfläche "Erstellen". Sie erhalten eine Erfolgsmeldung, und der neue Speicher wird in Ihrer Liste der Vektor-Speicher angezeigt.
Konfigurationsoptionen
Einbettungsmodelle
Modell
Dimensionen
Beschreibung
Am besten geeignet für
openai/text-embedding-3-large
1536
Hochgenaues Einbettungsmodell von OpenAI
Produktionsanwendungen, die maximale Genauigkeit erfordern
openai/text-embedding-3-small
1536
Kleineres, schnelleres Einbettungsmodell von OpenAI
Anwendungen mit höheren Durchsatzanforderungen
Indexierungsalgorithmen
Algorithmus
Beschreibung
Kompromisse
IVFFLAT (Standard)
Umgekehrte Datei mit flacher Kompression
Gute Balance zwischen Geschwindigkeit und Genauigkeit; funktioniert gut für die meisten Datensätze
HNSW
Hierarchisches navigierbares kleines Welt
Bessere Genauigkeit für große Datensätze; höhere Speicheranforderungen
Suchmetriken
Metrik
Beschreibung
Am besten geeignet für
cosinus (Standard)
Misst den Winkel zwischen Vektoren
Allgemeine Ähnlichkeitsabgleichung
inneres Produkt (ip)
Skalarprodukt zwischen Vektoren
Wenn die Vektormagnitude wichtig ist
L2 (Euklidisch)
Luftlinienentfernung zwischen Vektoren
Wenn räumliche Beziehungen wichtig sind
Verwaltung von Vektor-Speichern
Vektor-Speicher anzeigen und bearbeiten:
Greifen Sie auf das Verwaltungs-Dashboard zu, um Vektor-Speicher anzuzeigen, zu bearbeiten oder zu löschen.
Dokumente anzeigen:
Durchsuchen Sie einzelne Dokumente und deren zugehörige Metadaten innerhalb eines bestimmten Vektor-Speichers.
Statistiken:
Sehen Sie sich detaillierte Statistiken wie die Anzahl der gespeicherten Vektoren, die Abfrageleistung und betriebliche Kennzahlen an.
API-Schlüsselverwaltung
API-Schlüssel werden verwendet, um den Zugriff auf die API-Endpunkte des Rememberizer Vector Store zu authentifizieren und zu autorisieren. Eine ordnungsgemäße Verwaltung der API-Schlüssel ist entscheidend für die Aufrechterhaltung der Sicherheit und Integrität Ihrer Vektor-Stores.
Erstellen von API-Schlüsseln
Gehen Sie zu Ihrer Seite mit den Details zum Vector Store
Navigieren Sie zum Abschnitt zur Verwaltung von API-Schlüsseln:
Er kann im Tab "Konfiguration" gefunden werden
Klicken Sie auf "API-Schlüssel hinzufügen":
Ein Formular wird angezeigt, das Sie auffordert, Details einzugeben.
Füllen Sie die Details aus:
Name: Geben Sie einen Namen für den API-Schlüssel an, um Ihnen zu helfen, seinen Anwendungsfall zu identifizieren.
Reichen Sie das Formular ein:
Klicken Sie auf die Schaltfläche "Erstellen". Der neue API-Schlüssel wird generiert und angezeigt. Stellen Sie sicher, dass Sie ihn kopieren und sicher aufbewahren. Dieser Schlüssel wird verwendet, um Anfragen an diesen speziellen Vector Store zu authentifizieren.
Widerrufen von API-Schlüsseln
Wenn ein API-Schlüssel nicht mehr benötigt wird, können Sie ihn löschen, um möglichen Missbrauch zu verhindern.
Aus Sicherheitsgründen möchten Sie möglicherweise Ihre API-Schlüssel regelmäßig rotieren. Dies beinhaltet das Generieren eines neuen Schlüssels und das Widerrufen des alten.
Verwendung der Vector Store API
Nachdem Sie einen Vector Store erstellt und einen API-Schlüssel generiert haben, können Sie über die REST API mit ihm interagieren.
Codebeispiele
import requests
import json
API_KEY = "your_api_key_here"
VECTOR_STORE_ID = "vs_abc123" # Ersetzen Sie dies durch Ihre Vektor-Store-ID
BASE_URL = "https://api.rememberizer.ai/api/v1"
Dokument in den Vektor-Speicher hochladen
def upload_document(file_path, document_name=None):
if document_name is None:
document_name = file_path.split("/")[-1]
with open(file_path, "rb") as f:
files = {"file": (document_name, f)}
headers = {"x-api-key": API_KEY}
response = requests.post(
f"{BASE_URL}/vector-stores/{VECTOR_STORE_ID}/documents",
headers=headers,
files=files
)
if response.status_code == 201:
print(f"Dokument '{document_name}' erfolgreich hochgeladen!")
return response.json()
else:
print(f"Fehler beim Hochladen des Dokuments: {response.text}")
return None
results = client.search('Was sind die besten Praktiken für Datensicherheit?')
puts "Gefunden #{results['matched_chunks'].length} Ergebnisse"
Zeige das beste Ergebnis an
if results['matched_chunks'].any?
top_match = results['matched_chunks'].first
puts "Bester Treffer (Distanz: #{top_match['distance']}):"
puts "Dokument: #{top_match['document']['name']}"
puts "Inhalt: #{top_match['matched_content']}"
end
=end
</div>
<div data-gb-custom-block data-tag="tab" data-title='cURL'>
```bash
# Setzen Sie Ihren API-Schlüssel und die Vector Store-ID
API_KEY="your_api_key_here"
VECTOR_STORE_ID="vs_abc123"
BASE_URL="https://api.rememberizer.ai/api/v1"
# Informationen zum Vektor-Store abrufen
curl -X GET "${BASE_URL}/vector-stores/${VECTOR_STORE_ID}" \
-H "x-api-key: ${API_KEY}"
# Laden Sie ein Textdokument hoch
curl -X POST "${BASE_URL}/vector-stores/${VECTOR_STORE_ID}/documents/text" \
-H "x-api-key: ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "example-document.txt",
"content": "Dies ist ein Beispiel-Dokument, das vektorisiert und in der Vektordatenbank für die semantische Suche gespeichert wird."
}'
# Eine Datei hochladen
curl -X POST "${BASE_URL}/vector-stores/${VECTOR_STORE_ID}/documents" \
-H "x-api-key: ${API_KEY}" \
-F "file=@/path/to/your/document.pdf"
# Suche nach Dokumenten
curl -X GET "${BASE_URL}/vector-stores/${VECTOR_STORE_ID}/documents/search?q=semantische%20suche&n=5&prev_chunks=1&next_chunks=1" \
-H "x-api-key: ${API_KEY}"
# Alle Dokumente auflisten
curl -X GET "${BASE_URL}/vector-stores/${VECTOR_STORE_ID}/documents" \
-H "x-api-key: ${API_KEY}"
# Löschen eines Dokuments
curl -X DELETE "${BASE_URL}/vector-stores/${VECTOR_STORE_ID}/documents/123" \
-H "x-api-key: ${API_KEY}"
Leistungsüberlegungen
Demnächst: Architekturdiagramm des Vektor-Speichers
Dieses technische Architekturdiagramm wird veranschaulichen:
Die Architektur der PostgreSQL + pgvector-Grundlage
Strukturen der Indexierungsalgorithmen (IVFFLAT vs. HNSW)
Wie Suchmetriken im Vektorraum funktionieren (visueller Vergleich)
Dokumentchunking-Prozess mit Überlappungsvisualisierung
Leistungsüberlegungen, die über verschiedene Skalen visualisiert werden
Optimierung für verschiedene Datenmengen
Datenmenge
Empfohlene Konfiguration
Hinweise
Klein (<10k Dokumente)
IVFFLAT, Kosinusähnlichkeit
Einfache Konfiguration bietet gute Leistung
Mittel (10k-100k Dokumente)
IVFFLAT, regelmäßige Neuanordnung sicherstellen
Balance zwischen Suchgeschwindigkeit und Indexpflege
Groß (>100k Dokumente)
HNSW, Erwägung der Erhöhung der Vektordimensionen
Höherer Speicherverbrauch, aber hält die Leistung im großen Maßstab
Chunking-Strategien
Der Chunking-Prozess hat einen erheblichen Einfluss auf die Suchqualität:
Chunk-Größe: Rememberizer verwendet eine Standard-Chunk-Größe von 1024 Bytes mit einer Überlappung von 200 Bytes
Kleinere Chunks (512-1024 Bytes): Präzisere Übereinstimmungen, besser für spezifische Fragen
Größere Chunks (1500-2048 Bytes): Mehr Kontext in jeder Übereinstimmung, besser für breitere Themen
Überlappung: Stellt sicher, dass der Kontext an den Chunk-Grenzen nicht verloren geht
Abfrageoptimierung
Kontextfenster: Verwenden Sie prev_chunks und next_chunks, um umgebende Inhalte abzurufen
Ergebnisanzahl: Beginnen Sie mit 3-5 Ergebnissen (n-Parameter) und passen Sie diese je nach Präzisionsbedarf an
Schwellenwert: Passen Sie den t-Parameter an, um Ergebnisse nach Ähnlichkeitspunktzahl zu filtern
Erweiterte Nutzung
Neuindizierung
Rememberizer löst automatisch eine Neuindizierung aus, wenn die Vektoranzahlen vordefinierte Schwellenwerte überschreiten, aber ziehen Sie eine manuelle Neuindizierung in Betracht nach:
Hochladen einer großen Anzahl von Dokumenten
Ändern des Einbettungsmodells
Modifizieren des Indizierungsalgorithmus
Abfrageverbesserung
Für bessere Suchergebnisse:
Seien Sie spezifisch in Suchanfragen
Fügen Sie Kontext hinzu, wenn möglich
Verwenden Sie natürliche Sprache anstelle von Schlüsselwörtern
Passen Sie die Parameter an basierend auf der Ergebnisqualität
Migration von anderen Vektor-Datenbanken
Wenn Sie derzeit andere Vektor-Datenbanklösungen verwenden und zu Rememberizer Vector Store migrieren möchten, helfen Ihnen die folgenden Anleitungen, Ihre Daten effizient zu übertragen.
Migrationsübersicht
Die Migration von Vektordaten umfasst:
Exportieren von Daten aus Ihrer Quell-Vektordatenbank
Konvertieren der Daten in ein mit Rememberizer kompatibles Format
Importieren der Daten in Ihren Rememberizer Vektor-Speicher
Überprüfen, ob die Migration erfolgreich war
Vorteile der Migration zu Rememberizer
PostgreSQL-Grundlage: Basierend auf reifer Datenbanktechnologie mit integrierter Sicherung und Wiederherstellung
Integriertes Ökosystem: Nahtlose Verbindung mit anderen Rememberizer-Komponenten
Vereinfachte Verwaltung: Einheitliche Schnittstelle für Vektoroperationen
Erweiterte Sicherheit: Zeilenbasierte Sicherheit und feingranulare Zugriffskontrollen
Skalierbare Architektur: Leistungsoptimierung, während Ihre Daten wachsen
Migration von Pinecone
import os
import pinecone
import requests
import json
import time
# Richten Sie den Pinecone-Client ein
pinecone.init(api_key="PINECONE_API_KEY", environment="PINECONE_ENV")
source_index = pinecone.Index("your-pinecone-index")
# Richten Sie den Rememberizer Vector Store-Client ein
REMEMBERIZER_API_KEY = "your_rememberizer_api_key"
VECTOR_STORE_ID = "vs_abc123" # Ihre Rememberizer-Vektorstore-ID
BASE_URL = "https://api.rememberizer.ai/api/v1"
# 1. Batchgröße für die Migration festlegen (an Ihre Datengröße anpassen)
BATCH_SIZE = 100
# 2. Funktion zum Abrufen von Vektoren aus Pinecone
def fetch_vectors_from_pinecone(index_name, batch_size, cursor=None):
# Verwenden Sie die Listenoperation, wenn sie in Ihrer Pinecone-Version verfügbar ist
try:
result = source_index.list(limit=batch_size, cursor=cursor)
vectors = result.get("vectors", {})
next_cursor = result.get("cursor")
return vectors, next_cursor
except AttributeError:
# Für ältere Pinecone-Versionen ohne Listenoperation
# Dies ist ein vereinfachter Ansatz; die tatsächliche Implementierung hängt von Ihrem Datenzugriffsmuster ab
query_response = source_index.query(
vector=[0] * source_index.describe_index_stats()["dimension"],
top_k=batch_size,
include_metadata=True,
include_values=True
)
return {item.id: {"id": item.id, "values": item.values, "metadata": item.metadata}
for item in query_response.matches}, None
# 3. Funktion zum Hochladen von Vektoren zu Rememberizer
def upload_to_rememberizer(vectors):
headers = {
"x-api-key": REMEMBERIZER_API_KEY,
"Content-Type": "application/json"
}
for vector_id, vector_data in vectors.items():
# Konvertiere Pinecone-Vektordaten in Rememberizer-Format
document_name = vector_data.get("metadata", {}).get("filename", f"pinecone_doc_{vector_id}")
content = vector_data.get("metadata", {}).get("text", "")
if not content:
print(f"Überspringe {vector_id} - kein Textinhalt in den Metadaten gefunden")
continue
data = {
"name": document_name,
"content": content,
# Optional: zusätzliche Metadaten einfügen
"metadata": vector_data.get("metadata", {})
}
response = requests.post(
f"{BASE_URL}/vector-stores/{VECTOR_STORE_ID}/documents/text",
headers=headers,
json=data
)
if response.status_code == 201:
print(f"Dokument '{document_name}' erfolgreich hochgeladen!")
else:
print(f"Fehler beim Hochladen des Dokuments {document_name}: {response.text}")
# Füge eine kleine Verzögerung hinzu, um eine Überlastung zu vermeiden
time.sleep(0.1)
# 4. Hauptmigrationfunktion
def migrate_pinecone_to_rememberizer():
cursor = None
total_migrated = 0
print("Migration von Pinecone zu Rememberizer startet...")
while True:
vectors, cursor = fetch_vectors_from_pinecone("your-pinecone-index", BATCH_SIZE, cursor)
if not vectors:
break
print(f"{len(vectors)} Vektoren von Pinecone abgerufen")
upload_to_rememberizer(vectors)
total_migrated += len(vectors)
print(f"Fortschritt: {total_migrated} Vektoren migriert")
if not cursor:
break
print(f"Migration abgeschlossen! Insgesamt {total_migrated} Vektoren zu Rememberizer migriert")
# Führen Sie die Migration durch
# migrate_pinecone_to_rememberizer()
const { PineconeClient } = require('@pinecone-database/pinecone');
const axios = require('axios');
// Pinecone-Konfiguration
const pineconeApiKey = 'PINECONE_API_KEY';
const pineconeEnvironment = 'PINECONE_ENVIRONMENT';
const pineconeIndexName = 'YOUR_PINECONE_INDEX';
// Rememberizer-Konfiguration
const rememberizerApiKey = 'YOUR_REMEMBERIZER_API_KEY';
const vectorStoreId = 'vs_abc123';
const baseUrl = 'https://api.rememberizer.ai/api/v1';
// Batch-Größe Konfiguration
const BATCH_SIZE = 100;
// Pinecone-Client initialisieren
async function initPinecone() {
const pinecone = new PineconeClient();
await pinecone.init({
apiKey: pineconeApiKey,
environment: pineconeEnvironment,
});
return pinecone;
}
// Vektoren von Pinecone abrufen
async function fetchVectorsFromPinecone(pinecone, batchSize, paginationToken = null) {
const index = pinecone.Index(pineconeIndexName);
try {
// Für neuere Pinecone-Versionen
const listResponse = await index.list({
limit: batchSize,
paginationToken: paginationToken
});
return {
vectors: listResponse.vectors || {},
nextToken: listResponse.paginationToken
};
} catch (error) {
// Fallback für ältere Pinecone-Versionen
// Dies ist vereinfacht; die tatsächliche Implementierung hängt von Ihrem Datenzugriffsmuster ab
const stats = await index.describeIndexStats();
const dimension = stats.dimension;
const queryResponse = await index.query({
vector: Array(dimension).fill(0),
topK: batchSize,
includeMetadata: true,
includeValues: true
});
const vectors = {};
queryResponse.matches.forEach(match => {
vectors[match.id] = {
id: match.id,
values: match.values,
metadata: match.metadata
};
});
return { vectors, nextToken: null };
}
}
// Vektoren zu Rememberizer hochladen
async function uploadToRememberizer(vectors) {
const headers = {
'x-api-key': rememberizerApiKey,
'Content-Type': 'application/json'
};
const results = [];
for (const [vectorId, vectorData] of Object.entries(vectors)) {
const documentName = vectorData.metadata?.filename || `pinecone_doc_${vectorId}`;
const content = vectorData.metadata?.text || '';
if (!content) {
console.log(`Überspringe ${vectorId} - kein Textinhalt in den Metadaten gefunden`);
continue;
}
const data = {
name: documentName,
content: content,
// Optional: zusätzliche Metadaten einfügen
metadata: vectorData.metadata || {}
};
try {
const response = await axios.post(
`${baseUrl}/vector-stores/${vectorStoreId}/documents/text`,
data,
{ headers }
);
if (response.status === 201) {
console.log(`Dokument '${documentName}' erfolgreich hochgeladen!`);
results.push({ id: vectorId, success: true });
} else {
console.error(`Fehler beim Hochladen des Dokuments ${documentName}: ${response.statusText}`);
results.push({ id: vectorId, success: false, error: response.statusText });
}
} catch (error) {
console.error(`Fehler beim Hochladen des Dokuments ${documentName}: ${error.message}`);
results.push({ id: vectorId, success: false, error: error.message });
}
// Eine kleine Verzögerung hinzufügen, um eine Ratenbegrenzung zu verhindern
await new Promise(resolve => setTimeout(resolve, 100));
}
return results;
}
// Hauptmigrationsfunktion
async function migratePineconeToRememberizer() {
try {
console.log('Migration von Pinecone zu Rememberizer startet...');
const pinecone = await initPinecone();
let nextToken = null;
let totalMigrated = 0;
do {
const { vectors, nextToken: token } = await fetchVectorsFromPinecone(
pinecone,
BATCH_SIZE,
nextToken
);
nextToken = token;
if (Object.keys(vectors).length === 0) {
break;
}
console.log(`${Object.keys(vectors).length} Vektoren von Pinecone abgerufen`);
const results = await uploadToRememberizer(vectors);
const successCount = results.filter(r => r.success).length;
totalMigrated += successCount;
console.log(`Fortschritt: ${totalMigrated} Vektoren erfolgreich migriert`);
} while (nextToken);
console.log(`Migration abgeschlossen! ${totalMigrated} insgesamt Vektoren zu Rememberizer migriert`);
} catch (error) {
console.error('Migration fehlgeschlagen:', error);
}
}
// Migration ausführen
// migratePineconeToRememberizer();
Migration von Qdrant
import requests
import json
import time
from qdrant_client import QdrantClient
from qdrant_client.http import models as rest
# Richten Sie den Qdrant-Client ein
QDRANT_URL = "http://localhost:6333" # oder Ihre Qdrant-Cloud-URL
QDRANT_API_KEY = "your_qdrant_api_key" # falls Sie Qdrant Cloud verwenden
QDRANT_COLLECTION_NAME = "your_collection"
qdrant_client = QdrantClient(
url=QDRANT_URL,
api_key=QDRANT_API_KEY # Nur für Qdrant Cloud
)
# Richten Sie den Rememberizer Vector Store-Client ein
REMEMBERIZER_API_KEY = "your_rememberizer_api_key"
VECTOR_STORE_ID = "vs_abc123" # Ihre Rememberizer-Vektorstore-ID
BASE_URL = "https://api.rememberizer.ai/api/v1"
# Batch-Größe für die Verarbeitung
BATCH_SIZE = 100
# Funktion zum Abrufen von Punkten aus Qdrant
def fetch_points_from_qdrant(collection_name, batch_size, offset=0):
try:
# Sammlung Informationen abrufen, um die Vektor-Dimension zu bestimmen
collection_info = qdrant_client.get_collection(collection_name=collection_name)
# Durch Punkte scrollen
scroll_result = qdrant_client.scroll(
collection_name=collection_name,
limit=batch_size,
offset=offset,
with_payload=True,
with_vectors=True
)
points = scroll_result[0] # Tupel von (punkten, next_offset)
next_offset = scroll_result[1]
return points, next_offset
except Exception as e:
print(f"Fehler beim Abrufen von Punkten aus Qdrant: {e}")
return [], None
# Funktion zum Hochladen von Vektoren zu Rememberizer
def upload_to_rememberizer(points):
headers = {
"x-api-key": REMEMBERIZER_API_KEY,
"Content-Type": "application/json"
}
results = []
for point in points:
# Daten aus dem Qdrant-Punkt extrahieren
point_id = point.id
metadata = point.payload
text_content = metadata.get("text", "")
document_name = metadata.get("filename", f"qdrant_doc_{point_id}")
if not text_content:
print(f"Überspringe {point_id} - kein Textinhalt im Payload gefunden")
continue
data = {
"name": document_name,
"content": text_content,
# Optional: zusätzliche Metadaten einfügen
"metadata": metadata
}
try:
response = requests.post(
f"{BASE_URL}/vector-stores/{VECTOR_STORE_ID}/documents/text",
headers=headers,
json=data
)
if response.status_code == 201:
print(f"Dokument '{document_name}' erfolgreich hochgeladen!")
results.append({"id": point_id, "success": True})
else:
print(f"Fehler beim Hochladen des Dokuments {document_name}: {response.text}")
results.append({"id": point_id, "success": False, "error": response.text})
except Exception as e:
print(f"Ausnahme beim Hochladen des Dokuments {document_name}: {str(e)}")
results.append({"id": point_id, "success": False, "error": str(e)})
# Eine kleine Verzögerung hinzufügen, um Ratenbegrenzung zu vermeiden
time.sleep(0.1)
return results
# Hauptmigrationsfunktion
def migrate_qdrant_to_rememberizer():
offset = None
total_migrated = 0
print("Migration von Qdrant zu Rememberizer startet...")
while True:
points, next_offset = fetch_points_from_qdrant(
QDRANT_COLLECTION_NAME,
BATCH_SIZE,
offset
)
if not points:
break
print(f"{len(points)} Punkte von Qdrant abgerufen")
results = upload_to_rememberizer(points)
success_count = sum(1 for r in results if r.get("success", False))
total_migrated += success_count
print(f"Fortschritt: {total_migrated} Punkte erfolgreich migriert")
if next_offset is None:
break
offset = next_offset
print(f"Migration abgeschlossen! Insgesamt {total_migrated} Punkte zu Rememberizer migriert")
# Führen Sie die Migration durch
# migrate_qdrant_to_rememberizer()
const { QdrantClient } = require('@qdrant/js-client-rest');
const axios = require('axios');
// Qdrant-Konfiguration
const qdrantUrl = 'http://localhost:6333'; // oder Ihre Qdrant-Cloud-URL
const qdrantApiKey = 'your_qdrant_api_key'; // falls Sie Qdrant Cloud verwenden
const qdrantCollectionName = 'your_collection';
// Rememberizer-Konfiguration
const rememberizerApiKey = 'YOUR_REMEMBERIZER_API_KEY';
const vectorStoreId = 'vs_abc123';
const baseUrl = 'https://api.rememberizer.ai/api/v1';
// Batch-Größe Konfiguration
const BATCH_SIZE = 100;
// Qdrant-Client initialisieren
const qdrantClient = new QdrantClient({
url: qdrantUrl,
apiKey: qdrantApiKey // Nur für Qdrant Cloud
});
// Punkte von Qdrant abrufen
async function fetchPointsFromQdrant(collectionName, batchSize, offset = 0) {
try {
// Sammlung Informationen abrufen
const collectionInfo = await qdrantClient.getCollection(collectionName);
// Durch Punkte scrollen
const scrollResult = await qdrantClient.scroll(collectionName, {
limit: batchSize,
offset: offset,
with_payload: true,
with_vectors: true
});
return {
points: scrollResult.points,
nextOffset: scrollResult.next_page_offset
};
} catch (error) {
console.error(`Fehler beim Abrufen von Punkten aus Qdrant: ${error.message}`);
return { points: [], nextOffset: null };
}
}
// Vektoren zu Rememberizer hochladen
async function uploadToRememberizer(points) {
const headers = {
'x-api-key': rememberizerApiKey,
'Content-Type': 'application/json'
};
const results = [];
for (const point of points) {
// Daten aus dem Qdrant-Punkt extrahieren
const pointId = point.id;
const metadata = point.payload || {};
const textContent = metadata.text || '';
const documentName = metadata.filename || `qdrant_doc_${pointId}`;
if (!textContent) {
console.log(`Überspringe ${pointId} - kein Textinhalt im Payload gefunden`);
continue;
}
const data = {
name: documentName,
content: textContent,
// Optional: zusätzliche Metadaten einfügen
metadata: metadata
};
try {
const response = await axios.post(
`${baseUrl}/vector-stores/${vectorStoreId}/documents/text`,
data,
{ headers }
);
if (response.status === 201) {
console.log(`Dokument '${documentName}' erfolgreich hochgeladen!`);
results.push({ id: pointId, success: true });
} else {
console.error(`Fehler beim Hochladen des Dokuments ${documentName}: ${response.statusText}`);
results.push({ id: pointId, success: false, error: response.statusText });
}
} catch (error) {
console.error(`Fehler beim Hochladen des Dokuments ${documentName}: ${error.message}`);
results.push({ id: pointId, success: false, error: error.message });
}
// Eine kleine Verzögerung hinzufügen, um Ratenbegrenzung zu verhindern
await new Promise(resolve => setTimeout(resolve, 100));
}
return results;
}
// Hauptmigrationsfunktion
async function migrateQdrantToRememberizer() {
try {
console.log('Migration von Qdrant zu Rememberizer startet...');
let offset = null;
let totalMigrated = 0;
do {
const { points, nextOffset } = await fetchPointsFromQdrant(
qdrantCollectionName,
BATCH_SIZE,
offset
);
offset = nextOffset;
if (points.length === 0) {
break;
}
console.log(`${points.length} Punkte von Qdrant abgerufen`);
const results = await uploadToRememberizer(points);
const successCount = results.filter(r => r.success).length;
totalMigrated += successCount;
console.log(`Fortschritt: ${totalMigrated} Punkte erfolgreich migriert`);
} while (offset !== null);
console.log(`Migration abgeschlossen! ${totalMigrated} insgesamt Punkte zu Rememberizer migriert`);
} catch (error) {
console.error('Migration fehlgeschlagen:', error);
}
}
// Migration ausführen
// migrateQdrantToRememberizer();
Migration von Supabase pgvector
Wenn Sie bereits Supabase mit pgvector verwenden, ist die Migration zu Rememberizer besonders einfach, da beide PostgreSQL mit der pgvector-Erweiterung verwenden.
import psycopg2
import requests
import json
import time
import os
from dotenv import load_dotenv
# Lade Umgebungsvariablen
load_dotenv()
# Supabase PostgreSQL-Konfiguration
SUPABASE_DB_HOST = os.getenv("SUPABASE_DB_HOST")
SUPABASE_DB_PORT = os.getenv("SUPABASE_DB_PORT", "5432")
SUPABASE_DB_NAME = os.getenv("SUPABASE_DB_NAME")
SUPABASE_DB_USER = os.getenv("SUPABASE_DB_USER")
SUPABASE_DB_PASSWORD = os.getenv("SUPABASE_DB_PASSWORD")
SUPABASE_VECTOR_TABLE = os.getenv("SUPABASE_VECTOR_TABLE", "documents")
# Rememberizer-Konfiguration
REMEMBERIZER_API_KEY = os.getenv("REMEMBERIZER_API_KEY")
VECTOR_STORE_ID = os.getenv("VECTOR_STORE_ID") # z.B. "vs_abc123"
BASE_URL = "https://api.rememberizer.ai/api/v1"
# Batch-Größe für die Verarbeitung
BATCH_SIZE = 100
# Mit Supabase PostgreSQL verbinden
def connect_to_supabase():
try:
conn = psycopg2.connect(
host=SUPABASE_DB_HOST,
port=SUPABASE_DB_PORT,
dbname=SUPABASE_DB_NAME,
user=SUPABASE_DB_USER,
password=SUPABASE_DB_PASSWORD
)
return conn
except Exception as e:
print(f"Fehler beim Verbinden mit Supabase PostgreSQL: {e}")
return None
# Dokumente von Supabase pgvector abrufen
def fetch_documents_from_supabase(conn, batch_size, offset=0):
try:
cursor = conn.cursor()
# Passen Sie diese Abfrage basierend auf Ihrer Tabellenstruktur an
query = f"""
SELECT id, content, metadata, embedding
FROM {SUPABASE_VECTOR_TABLE}
ORDER BY id
LIMIT %s OFFSET %s
"""
cursor.execute(query, (batch_size, offset))
documents = cursor.fetchall()
cursor.close()
return documents
except Exception as e:
print(f"Fehler beim Abrufen von Dokumenten von Supabase: {e}")
return []
# Dokumente an Rememberizer hochladen
def upload_to_rememberizer(documents):
headers = {
"x-api-key": REMEMBERIZER_API_KEY,
"Content-Type": "application/json"
}
results = []
for doc in documents:
doc_id, content, metadata, embedding = doc
# Metadaten analysieren, wenn sie als JSON-String gespeichert sind
if isinstance(metadata, str):
try:
metadata = json.loads(metadata)
except:
metadata = {}
elif metadata is None:
metadata = {}
document_name = metadata.get("filename", f"supabase_doc_{doc_id}")
if not content:
print(f"Überspringe {doc_id} - kein Inhalt gefunden")
continue
data = {
"name": document_name,
"content": content,
"metadata": metadata
}
try:
response = requests.post(
f"{BASE_URL}/vector-stores/{VECTOR_STORE_ID}/documents/text",
headers=headers,
json=data
)
if response.status_code == 201:
print(f"Dokument '{document_name}' erfolgreich hochgeladen!")
results.append({"id": doc_id, "success": True})
else:
print(f"Fehler beim Hochladen des Dokuments {document_name}: {response.text}")
results.append({"id": doc_id, "success": False, "error": response.text})
except Exception as e:
print(f"Ausnahme beim Hochladen des Dokuments {document_name}: {str(e)}")
results.append({"id": doc_id, "success": False, "error": str(e)})
# Eine kleine Verzögerung hinzufügen, um eine Überlastung zu vermeiden
time.sleep(0.1)
return results
# Hauptmigration Funktion
def migrate_supabase_to_rememberizer():
conn = connect_to_supabase()
if not conn:
print("Verbindung zu Supabase fehlgeschlagen. Migration wird abgebrochen.")
return
offset = 0
total_migrated = 0
print("Migration von Supabase pgvector zu Rememberizer beginnt...")
try:
while True:
documents = fetch_documents_from_supabase(conn, BATCH_SIZE, offset)
if not documents:
break
print(f"{len(documents)} Dokumente von Supabase abgerufen")
results = upload_to_rememberizer(documents)
success_count = sum(1 for r in results if r.get("success", False))
total_migrated += success_count
print(f"Fortschritt: {total_migrated} Dokumente erfolgreich migriert")
offset += BATCH_SIZE
finally:
conn.close()
print(f"Migration abgeschlossen! Insgesamt {total_migrated} Dokumente nach Rememberizer migriert")
# Führen Sie die Migration durch
# migrate_supabase_to_rememberizer()
const { Pool } = require('pg');
const axios = require('axios');
require('dotenv').config();
// Supabase PostgreSQL-Konfiguration
const supabasePool = new Pool({
host: process.env.SUPABASE_DB_HOST,
port: process.env.SUPABASE_DB_PORT || 5432,
database: process.env.SUPABASE_DB_NAME,
user: process.env.SUPABASE_DB_USER,
password: process.env.SUPABASE_DB_PASSWORD,
ssl: {
rejectUnauthorized: false
}
});
const supabaseVectorTable = process.env.SUPABASE_VECTOR_TABLE || 'documents';
// Rememberizer-Konfiguration
const rememberizerApiKey = process.env.REMEMBERIZER_API_KEY;
const vectorStoreId = process.env.VECTOR_STORE_ID; // z.B. "vs_abc123"
const baseUrl = 'https://api.rememberizer.ai/api/v1';
// Batch-Größe Konfiguration
const BATCH_SIZE = 100;
// Dokumente von Supabase pgvector abrufen
async function fetchDocumentsFromSupabase(batchSize, offset = 0) {
try {
// Passen Sie diese Abfrage basierend auf Ihrer Tabellenstruktur an
const query = `
SELECT id, content, metadata, embedding
FROM ${supabaseVectorTable}
ORDER BY id
LIMIT $1 OFFSET $2
`;
const result = await supabasePool.query(query, [batchSize, offset]);
return result.rows;
} catch (error) {
console.error(`Fehler beim Abrufen von Dokumenten aus Supabase: ${error.message}`);
return [];
}
}
// Dokumente zu Rememberizer hochladen
async function uploadToRememberizer(documents) {
const headers = {
'x-api-key': rememberizerApiKey,
'Content-Type': 'application/json'
};
const results = [];
for (const doc of documents) {
// Metadaten parsen, falls sie als JSON-String gespeichert sind
let metadata = doc.metadata;
if (typeof metadata === 'string') {
try {
metadata = JSON.parse(metadata);
} catch (e) {
metadata = {};
}
} else if (metadata === null) {
metadata = {};
}
const documentName = metadata.filename || `supabase_doc_${doc.id}`;
if (!doc.content) {
console.log(`Überspringe ${doc.id} - kein Inhalt gefunden`);
continue;
}
const data = {
name: documentName,
content: doc.content,
metadata: metadata
};
try {
const response = await axios.post(
`${baseUrl}/vector-stores/${vectorStoreId}/documents/text`,
data,
{ headers }
);
if (response.status === 201) {
console.log(`Dokument '${documentName}' erfolgreich hochgeladen!`);
results.push({ id: doc.id, success: true });
} else {
console.error(`Fehler beim Hochladen des Dokuments ${documentName}: ${response.statusText}`);
results.push({ id: doc.id, success: false, error: response.statusText });
}
} catch (error) {
console.error(`Fehler beim Hochladen des Dokuments ${documentName}: ${error.message}`);
results.push({ id: doc.id, success: false, error: error.message });
}
// Fügen Sie eine kleine Verzögerung hinzu, um eine Überlastung zu vermeiden
await new Promise(resolve => setTimeout(resolve, 100));
}
return results;
}
// Hauptmigration Funktion
async function migrateSupabaseToRememberizer() {
try {
console.log('Migration von Supabase pgvector zu Rememberizer startet...');
let offset = 0;
let totalMigrated = 0;
while (true) {
const documents = await fetchDocumentsFromSupabase(BATCH_SIZE, offset);
if (documents.length === 0) {
break;
}
console.log(`${documents.length} Dokumente von Supabase abgerufen`);
const results = await uploadToRememberizer(documents);
const successCount = results.filter(r => r.success).length;
totalMigrated += successCount;
console.log(`Fortschritt: ${totalMigrated} Dokumente erfolgreich migriert`);
offset += BATCH_SIZE;
}
console.log(`Migration abgeschlossen! ${totalMigrated} insgesamt Dokumente zu Rememberizer migriert`);
} catch (error) {
console.error('Migration fehlgeschlagen:', error);
} finally {
await supabasePool.end();
}
}
// Migration ausführen
// migrateSupabaseToRememberizer();
Migrationsbest Practices
Befolgen Sie diese Empfehlungen für eine erfolgreiche Migration:
Vorausplanen:
Schätzen Sie das Datenvolumen und die für die Migration benötigte Zeit
Planen Sie die Migration während verkehrsärmerer Zeiten
Erhöhen Sie den Speicherplatz, bevor Sie große Migrationen starten
Zuerst Testen:
Erstellen Sie einen Test-Vektor-Speicher in Rememberizer
Migrieren Sie eine kleine Teilmenge von Daten (100-1000 Vektoren)
Überprüfen Sie die Suchfunktionalität mit wichtigen Abfragen
Datenvalidierung:
Vergleichen Sie die Dokumentenzahlen vor und nach der Migration
Führen Sie Benchmark-Abfragen durch, um ähnliche Ergebnisse sicherzustellen
Validieren Sie, dass Metadaten korrekt erhalten bleiben
Leistung optimieren:
Verwenden Sie Batch-Operationen für Effizienz
Berücksichtigen Sie die geografische Nähe von Quell- und Ziel-Datenbanken
Überwachen Sie die API-Ratenlimits und passen Sie die Batch-Größen entsprechend an
Nach der Migration:
Überprüfen Sie die Indexerstellung in Rememberizer
Aktualisieren Sie die Anwendungs-Konfigurationen, um auf den neuen Vektor-Speicher zu verweisen
Halten Sie die Quell-Datenbank als Backup, bis die Migration verifiziert ist