Rememberizer Docs
anmeldenMelden Sie sich anKontaktiere uns
Deutsch
Deutsch
  • Warum Rememberizer?
  • Hintergrund
    • Was sind Vektor-Embeddings und Vektor-Datenbanken?
    • Glossar
    • Standardisierte Terminologie
  • Persönliche Nutzung
    • Erste Schritte
      • Durchsuche dein Wissen
      • Zugriff auf Mementos-Filter
      • Allgemeines Wissen
      • Verwalte dein eingebettetes Wissen
  • Integrationen
    • Rememberizer App
    • Rememberizer Slack-Integration
    • Rememberizer Google Drive-Integration
    • Rememberizer Dropbox-Integration
    • Rememberizer Gmail-Integration
    • Rememberizer Memory-Integration
    • Rememberizer MCP-Server
    • Drittanbieter-Apps verwalten
  • Entwicklerressourcen
    • Entwicklerübersicht
  • Integrationsoptionen
    • Registrierung und Verwendung von API-Schlüsseln
    • Registrierung von Rememberizer-Apps
    • Autorisierung von Rememberizer-Apps
    • Erstellung eines Rememberizer GPT
    • LangChain-Integration
    • Vektor-Speicher
    • Talk-to-Slack die Beispiel-Webanwendung
  • Unternehmensintegration
    • Muster der Unternehmensintegration
  • API-Referenz
    • API-Dokumentation Startseite
    • Authentifizierung
  • Kern-APIs
    • Dokumente nach semantischer Ähnlichkeit suchen
    • Dokumente abrufen
    • Inhalte von Dokumenten abrufen
    • Slack-Inhalte abrufen
    • Inhalte an Rememberizer merken
  • Konto & Konfiguration
    • Aktuelle Kontodetails des Benutzers abrufen
    • Verfügbare Datenquellenintegrationen auflisten
    • Mementos
    • Alle hinzugefügten öffentlichen Kenntnisse abrufen
  • Vektor-Speicher-APIs
    • Dokumentation zum Vektor-Speicher
    • Vektor-Speicherinformationen abrufen
    • Liste der Dokumente in einem Vektor-Speicher abrufen
    • Dokumentinformationen abrufen
    • Neues Textdokument zu einem Vektor-Speicher hinzufügen
    • Dateien in einen Vektor-Speicher hochladen
    • Dateiinhalte in einem Vektor-Speicher aktualisieren
    • Ein Dokument im Vektor-Speicher entfernen
    • Nach Dokumenten im Vektor-Speicher anhand semantischer Ähnlichkeit suchen
  • Zusätzliche Ressourcen
    • Hinweise
      • Nutzungsbedingungen
      • Datenschutzrichtlinie
      • B2B
        • Über Reddit Agent
  • Veröffentlichungen
    • Versionshinweise Startseite
  • 2025 Veröffentlichungen
    • 25. Apr 2025
    • 18. Apr 2025
    • 11. Apr 2025
    • 4. Apr 2025
    • 28. Mär 2025
    • 21. Mär 2025
    • 14. Mär 2025
    • 17. Jan 2025
  • 2024 Veröffentlichungen
    • 27. Dez 2024
    • 20. Dez 2024
    • 13. Dez 2024
    • 6. Dez 2024
  • 29. Nov 2024
  • 22. Nov 2024
  • 15. Nov 2024
  • 8. Nov 2024
  • 1. Nov 2024
  • 25. Okt 2024
  • 18. Okt 2024
  • 11. Okt 2024
  • 4. Okt 2024
  • 27. Sep 2024
  • 20. Sep 2024
  • 13. Sep 2024
  • 16. Aug 2024
  • 9. Aug 2024
  • 2. Aug 2024
  • 26. Juli 2024
  • 12. Juli 2024
  • 28. Juni 2024
  • 14. Juni 2024
  • 31. Mai 2024
  • 17. Mai 2024
  • 10. Mai 2024
  • 26. Apr 2024
  • 19. Apr 2024
  • 12. Apr 2024
  • 5. Apr 2024
  • 25. März 2024
  • 18. März 2024
  • 11. März 2024
  • 4. März 2024
  • 26. Feb 2024
  • 19. Feb 2024
  • 12. Feb 2024
  • 5. Feb 2024
  • 29. Jan 2024
  • 22. Jan 2024
  • 15. Jan 2024
  • LLM-Dokumentation
    • Rememberizer LLM Bereit Dokumentation
Powered by GitBook
On this page
  • Vektor-Speicher
  • Einführung
  • Technische Übersicht
  • Erste Schritte
  • API-Schlüsselverwaltung
  • Verwendung der Vector Store API
  • Dokument in den Vektor-Speicher hochladen
  • Textinhalt in den Vektorstore hochladen
  • Suche im Vektor-Store
  • Beispielverwendung
  • dokument_hochladen("pfad/zum/dokument.pdf")
  • upload_text("Dies ist ein Beispieltext, der vektorisiert werden soll", "sample-document.txt")
  • search_vector_store("Wie funktioniert die Vektorsimilarität?")
  • Beispielverwendung
  • Suche nach Dokumenten
  • Zeige das beste Ergebnis an
  • Leistungsüberlegungen
  • Erweiterte Nutzung
  • Migration von anderen Vektor-Datenbanken
  1. Integrationsoptionen

Vektor-Speicher

Dieser Leitfaden hilft Ihnen zu verstehen, wie Sie den Rememberizer Vector Store als Entwickler nutzen können.

PreviousLangChain-IntegrationNextTalk-to-Slack die Beispiel-Webanwendung

Last updated 22 days ago

Vektor-Speicher

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:

  1. Semantische Suche: Dokumente basierend auf Bedeutung und nicht nur auf Schlüsselwörtern finden

  2. Ähnlichkeitsabgleich: Konzeptuell verwandte Inhalte identifizieren

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

  1. Navigieren Sie zum Abschnitt Vektor-Speicher in Ihrem Dashboard

  2. Klicken Sie auf "Neuen Vektor-Speicher erstellen":

    • Ein Formular wird angezeigt, das Sie auffordert, Details einzugeben.

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

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

  1. Vektor-Speicher anzeigen und bearbeiten:

    • Greifen Sie auf das Verwaltungs-Dashboard zu, um Vektor-Speicher anzuzeigen, zu bearbeiten oder zu löschen.

  2. Dokumente anzeigen:

    • Durchsuchen Sie einzelne Dokumente und deren zugehörige Metadaten innerhalb eines bestimmten Vektor-Speichers.

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

  1. Gehen Sie zu Ihrer Seite mit den Details zum Vector Store

  2. Navigieren Sie zum Abschnitt zur Verwaltung von API-Schlüsseln:

    • Er kann im Tab "Konfiguration" gefunden werden

  3. Klicken Sie auf "API-Schlüssel hinzufügen":

    • Ein Formular wird angezeigt, das Sie auffordert, Details einzugeben.

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

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

Textinhalt in den Vektorstore hochladen

def upload_text(content, document_name): headers = { "x-api-key": API_KEY, "Content-Type": "application/json" }

data = {
    "name": document_name,
    "content": content
}

response = requests.post(
    f"{BASE_URL}/vector-stores/{VECTOR_STORE_ID}/documents/text",
    headers=headers,
    json=data
)

if response.status_code == 201:
    print(f"Textdokument '{document_name}' erfolgreich hochgeladen!")
    return response.json()
else:
    print(f"Fehler beim Hochladen des Textes: {response.text}")
    return None

Suche im Vektor-Store

def search_vector_store(query, num_results=5, prev_chunks=1, next_chunks=1): headers = {"x-api-key": API_KEY}

params = {
    "q": query,
    "n": num_results,
    "prev_chunks": prev_chunks,
    "next_chunks": next_chunks
}

response = requests.get(
    f"{BASE_URL}/vector-stores/{VECTOR_STORE_ID}/documents/search",
    headers=headers,
    params=params
)

if response.status_code == 200:
    results = response.json()
    print(f"Gefunden: {len(results['matched_chunks'])} Übereinstimmungen für '{query}'")
    
    # Drucke das beste Ergebnis
    if results['matched_chunks']:
        top_match = results['matched_chunks'][0]
        print(f"Bester Treffer (Distanz: {top_match['distance']}):")
        print(f"Dokument: {top_match['document']['name']}")
        print(f"Inhalt: {top_match['matched_content']}")
    
    return results
else:
    print(f"Fehler bei der Suche: {response.text}")
    return None

Beispielverwendung

dokument_hochladen("pfad/zum/dokument.pdf")

upload_text("Dies ist ein Beispieltext, der vektorisiert werden soll", "sample-document.txt")

search_vector_store("Wie funktioniert die Vektorsimilarität?")


</div>

<div data-gb-custom-block data-tag="tab" data-title='JavaScript'>

```javascript
// Vector Store API Client
class VectorStoreClient {
  constructor(apiKey, vectorStoreId) {
    this.apiKey = apiKey;
    this.vectorStoreId = vectorStoreId;
    this.baseUrl = 'https://api.rememberizer.ai/api/v1';
  }

  // Informationen zum Vektor-Store abrufen
  async getVectorStoreInfo() {
    const response = await fetch(`${this.baseUrl}/vector-stores/${this.vectorStoreId}`, {
      method: 'GET',
      headers: {
        'x-api-key': this.apiKey
      }
    });
    
    if (!response.ok) {
      throw new Error(`Fehler beim Abrufen der Vektor-Store-Informationen: ${response.statusText}`);
    }
    
    return response.json();
  }

  // Ein Textdokument hochladen
  async uploadTextDocument(name, content) {
    const response = await fetch(`${this.baseUrl}/vector-stores/${this.vectorStoreId}/documents/text`, {
      method: 'POST',
      headers: {
        'x-api-key': this.apiKey,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        name,
        content
      })
    });
    
    if (!response.ok) {
      throw new Error(`Fehler beim Hochladen des Textdokuments: ${response.statusText}`);
    }
    
    return response.json();
  }

  // Eine Datei hochladen
  async uploadFile(file, onProgress) {
    const formData = new FormData();
    formData.append('file', file);
    
    const xhr = new XMLHttpRequest();
    
    return new Promise((resolve, reject) => {
      xhr.open('POST', `${this.baseUrl}/vector-stores/${this.vectorStoreId}/documents`);
      xhr.setRequestHeader('x-api-key', this.apiKey);
      
      xhr.upload.onprogress = (event) => {
        if (event.lengthComputable && onProgress) {
          const percentComplete = (event.loaded / event.total) * 100;
          onProgress(percentComplete);
        }
      };
      
      xhr.onload = () => {
        if (xhr.status === 201) {
          resolve(JSON.parse(xhr.responseText));
        } else {
          reject(new Error(`Fehler beim Hochladen der Datei: ${xhr.statusText}`));
        }
      };
      
      xhr.onerror = () => {
        reject(new Error('Netzwerkfehler beim Hochladen der Datei'));
      };
      
      xhr.send(formData);
    });
  }

  // Dokumente im Vektor-Store durchsuchen
  async searchDocuments(query, options = {}) {
    const params = new URLSearchParams({
      q: query,
      n: options.numResults || 10,
      prev_chunks: options.prevChunks || 1,
      next_chunks: options.nextChunks || 1
    });
    
    if (options.threshold) {
      params.append('t', options.threshold);
    }
    
    const response = await fetch(
      `${this.baseUrl}/vector-stores/${this.vectorStoreId}/documents/search?${params}`,
      {
        method: 'GET',
        headers: {
          'x-api-key': this.apiKey
        }
      }
    );
    
    if (!response.ok) {
      throw new Error(`Suche fehlgeschlagen: ${response.statusText}`);
    }
    
    return response.json();
  }

  // Alle Dokumente im Vektor-Store auflisten
  async listDocuments() {
    const response = await fetch(
      `${this.baseUrl}/vector-stores/${this.vectorStoreId}/documents`,
      {
        method: 'GET',
        headers: {
          'x-api-key': this.apiKey
        }
      }
    );
    
    if (!response.ok) {
      throw new Error(`Fehler beim Auflisten der Dokumente: ${response.statusText}`);
    }
    
    return response.json();
  }

  // Ein Dokument löschen
  async deleteDocument(documentId) {
    const response = await fetch(
      `${this.baseUrl}/vector-stores/${this.vectorStoreId}/documents/${documentId}`,
      {
        method: 'DELETE',
        headers: {
          'x-api-key': this.apiKey
        }
      }
    );
    
    if (!response.ok) {
      throw new Error(`Fehler beim Löschen des Dokuments: ${response.statusText}`);
    }
    
    return true;
  }
}

// Beispielverwendung
/*
const client = new VectorStoreClient('your_api_key', 'vs_abc123');

// Dokumente durchsuchen
client.searchDocuments('Wie funktioniert die semantische Suche?')
  .then(results => {
    console.log(`Gefundene ${results.matched_chunks.length} Übereinstimmungen`);
    results.matched_chunks.forEach(match => {
      console.log(`Dokument: ${match.document.name}`);
      console.log(`Punktzahl: ${match.distance}`);
      console.log(`Inhalt: ${match.matched_content}`);
      console.log('---');
    });
  })
  .catch(error => console.error(error));
*/
require 'net/http'
require 'uri'
require 'json'

class VectorStoreClient
  def initialize(api_key, vector_store_id)
    @api_key = api_key
    @vector_store_id = vector_store_id
    @base_url = 'https://api.rememberizer.ai/api/v1'
  end

  # Details zum Vektor-Store abrufen
  def get_vector_store_info
    uri = URI("#{@base_url}/vector-stores/#{@vector_store_id}")
    request = Net::HTTP::Get.new(uri)
    request['x-api-key'] = @api_key
    
    response = send_request(uri, request)
    JSON.parse(response.body)
  end

  # Textinhalt hochladen
  def upload_text(name, content)
    uri = URI("#{@base_url}/vector-stores/#{@vector_store_id}/documents/text")
    request = Net::HTTP::Post.new(uri)
    request['Content-Type'] = 'application/json'
    request['x-api-key'] = @api_key
    
    request.body = {
      name: name,
      content: content
    }.to_json
    
    response = send_request(uri, request)
    JSON.parse(response.body)
  end

  # Dokumente durchsuchen
  def search(query, num_results: 5, prev_chunks: 1, next_chunks: 1, threshold: nil)
    uri = URI("#{@base_url}/vector-stores/#{@vector_store_id}/documents/search")
    params = {
      q: query,
      n: num_results,
      prev_chunks: prev_chunks,
      next_chunks: next_chunks
    }
    
    params[:t] = threshold if threshold
    
    uri.query = URI.encode_www_form(params)
    request = Net::HTTP::Get.new(uri)
    request['x-api-key'] = @api_key
    
    response = send_request(uri, request)
    JSON.parse(response.body)
  end

  # Dokumente auflisten
  def list_documents
    uri = URI("#{@base_url}/vector-stores/#{@vector_store_id}/documents")
    request = Net::HTTP::Get.new(uri)
    request['x-api-key'] = @api_key
    
    response = send_request(uri, request)
    JSON.parse(response.body)
  end

  # Datei hochladen (Multipart-Form)
  def upload_file(file_path)
    uri = URI("#{@base_url}/vector-stores/#{@vector_store_id}/documents")
    
    file_name = File.basename(file_path)
    file_content = File.binread(file_path)
    
    boundary = "RememberizerBoundary#{rand(1000000)}"
    
    request = Net::HTTP::Post.new(uri)
    request['Content-Type'] = "multipart/form-data; boundary=#{boundary}"
    request['x-api-key'] = @api_key
    
    post_body = []
    post_body << "--#{boundary}\r\n"
    post_body << "Content-Disposition: form-data; name=\"file\"; filename=\"#{file_name}\"\r\n"
    post_body << "Content-Type: application/octet-stream\r\n\r\n"
    post_body << file_content
    post_body << "\r\n--#{boundary}--\r\n"
    
    request.body = post_body.join
    
    response = send_request(uri, request)
    JSON.parse(response.body)
  end

  private

  def send_request(uri, request)
    http = Net::HTTP.new(uri.host, uri.port)
    http.use_ssl = (uri.scheme == 'https')
    
    response = http.request(request)
    
    unless response.is_a?(Net::HTTPSuccess)
      raise "API-Anfrage fehlgeschlagen: #{response.code} #{response.message}\n#{response.body}"
    end
    
    response
  end
end

Beispielverwendung

=begin client = VectorStoreClient.new('your_api_key', 'vs_abc123')

Suche nach Dokumenten

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:

  1. Seien Sie spezifisch in Suchanfragen

  2. Fügen Sie Kontext hinzu, wenn möglich

  3. Verwenden Sie natürliche Sprache anstelle von Schlüsselwörtern

  4. 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:

  1. Exportieren von Daten aus Ihrer Quell-Vektordatenbank

  2. Konvertieren der Daten in ein mit Rememberizer kompatibles Format

  3. Importieren der Daten in Ihren Rememberizer Vektor-Speicher

  4. Ü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:

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

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

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

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

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

Für detaillierte API-Referenzen und Endpunktdokumentationen besuchen Sie die Dokumentation zum Vektor-Speicher-Seite.


Stellen Sie sicher, dass Sie die API-Schlüssel sicher verwalten und bewährte Praktiken für das Management von API-Schlüsseln befolgen.

Was sind Vektor-Embeddings und Vektordatenbanken?
Erstellen eines neuen Vektor-Speichers
Details eines Vektor-Speichers anzeigen
Erstellen eines neuen API-Schlüssels
Erstellen eines neuen Vektor-Speichers
Details eines Vektor-Speichers anzeigen
Erstellen eines neuen API-Schlüssels