Rememberizer Docs
Se connecterS'inscrireContactez-nous
Français
Français
  • Pourquoi Rememberizer ?
  • Contexte
    • Qu'est-ce que les embeddings vectoriels et les bases de données vectorielles ?
    • Glossaire
    • Terminologie standardisée
  • Utilisation personnelle
    • Commencer
      • Rechercher vos connaissances
      • Accès au filtre de souvenirs
      • Connaissances communes
      • Gérer vos connaissances intégrées
  • Intégrations
    • Application Rememberizer
    • Intégration Rememberizer Slack
    • Intégration Rememberizer Google Drive
    • Intégration Rememberizer Dropbox
    • Intégration Rememberizer Gmail
    • Intégration Rememberizer Memory
    • Serveurs MCP Rememberizer
    • Gérer les applications tierces
  • Ressources pour les développeurs
    • Aperçu des développeurs
  • Options d'intégration
    • Enregistrement et utilisation des clés API
    • Enregistrement des applications Rememberizer
    • Autorisation des applications Rememberizer
    • Création d'un GPT Rememberizer
    • Intégration LangChain
    • Magasins de vecteurs
    • Talk-to-Slack l'application Web d'exemple
  • Intégration d'entreprise
    • Modèles d'intégration d'entreprise
  • Référence API
    • Accueil de la documentation API
    • Authentification
  • APIs principales
    • Rechercher des documents par similarité sémantique
    • Récupérer des documents
    • Récupérer le contenu des documents
    • Récupérer le contenu Slack
    • Mémoriser le contenu dans Rememberizer
  • Compte & Configuration
    • Récupérer les détails du compte utilisateur actuel
    • Lister les intégrations de sources de données disponibles
    • Mementos
    • Obtenir toutes les connaissances publiques ajoutées
  • APIs de stockage vectoriel
    • Documentation sur le stockage vectoriel
    • Obtenir des informations sur le stockage vectoriel
    • Obtenir une liste de documents dans un stockage vectoriel
    • Obtenir des informations sur un document
    • Ajouter un nouveau document texte à un stockage vectoriel
    • Télécharger des fichiers dans un stockage vectoriel
    • Mettre à jour le contenu d'un fichier dans un stockage vectoriel
    • Supprimer un document dans le stockage vectoriel
    • Rechercher des documents de stockage vectoriel par similarité sémantique
  • Ressources supplémentaires
    • Avis
      • Conditions d'utilisation
      • Politique de confidentialité
      • B2B
        • À propos de Reddit Agent
  • Versions
    • Notes de version Accueil
  • Sorties 2025
    • 25 avr. 2025
    • 18 avr. 2025
    • 11 avr. 2025
    • 4 avr. 2025
    • 28 mar. 2025
    • 21 mar. 2025
    • 14 mar. 2025
    • 17 janv. 2025
  • Sorties 2024
    • 27 déc. 2024
    • 20 déc. 2024
    • 13 déc. 2024
    • 6 déc. 2024
  • 29 nov. 2024
  • 22 nov. 2024
  • 15 nov. 2024
  • 8 nov. 2024
  • 1er nov. 2024
  • 25 oct. 2024
  • 18 oct. 2024
  • 11 oct. 2024
  • 4 oct. 2024
  • 27 sept. 2024
  • 20 sept. 2024
  • 13 sept. 2024
  • 16 août 2024
  • 9 août 2024
  • 2 août 2024
  • 26 juil. 2024
  • 12 juil. 2024
  • 28 juin 2024
  • 14 juin 2024
  • 31 mai 2024
  • 17 mai 2024
  • 10 mai 2024
  • 26 avr. 2024
  • 19 avr. 2024
  • 12 avr. 2024
  • 5 avr. 2024
  • 25 mars 2024
  • 18 mars 2024
  • 11 mars 2024
  • 4 mars 2024
  • 26 févr. 2024
  • 19 févr. 2024
  • 12 févr. 2024
  • 5 févr. 2024
  • 29 janv. 2024
  • 22 janv. 2024
  • 15 janv. 2024
  • Documentation LLM
    • Documentation LLM Prête de Rememberizer
Powered by GitBook
On this page
  • Magasins de Vecteurs
  • Introduction
  • Vue d'ensemble technique
  • Commencer
  • Gestion des clés API
  • Utilisation de l'API Vector Store
  • Télécharger un document dans le magasin de vecteurs
  • Télécharger le contenu textuel vers le magasin de vecteurs
  • Rechercher dans le magasin de vecteurs
  • Exemple d'utilisation
  • télécharger_document("path/to/document.pdf")
  • upload_text("Ceci est un texte d'exemple à vectoriser", "sample-document.txt")
  • search_vector_store("Comment fonctionne la similarité vectorielle ?")
  • Exemple d'utilisation
  • Rechercher des documents
  • Afficher le meilleur résultat
  • Considérations de Performance
  • Utilisation Avancée
  • Migration depuis d'autres bases de données vectorielles
  1. Options d'intégration

Magasins de vecteurs

Ce guide vous aidera à comprendre comment utiliser le magasin de vecteurs Rememberizer en tant que développeur.

PreviousIntégration LangChainNextTalk-to-Slack l'application Web d'exemple

Last updated 22 days ago

Magasins de Vecteurs

Le Magasin de Vecteurs Rememberizer simplifie le processus de gestion des données vectorielles, vous permettant de vous concentrer sur l'entrée de texte et de tirer parti de la puissance des vecteurs pour diverses applications telles que la recherche et l'analyse de données.

Introduction

Le magasin de vecteurs Rememberizer fournit une interface facile à utiliser pour gérer les données vectorielles tout en abstraisant la complexité des embeddings vectoriels. Alimenté par PostgreSQL avec l'extension pgvector, le magasin de vecteurs Rememberizer vous permet de travailler directement avec du texte. Le service gère le découpage, la vectorisation et le stockage des données textuelles, vous permettant de vous concentrer sur la logique principale de votre application.

Pour une compréhension plus approfondie des concepts théoriques derrière les embeddings vectoriels et les bases de données vectorielles, consultez .

Vue d'ensemble technique

Comment fonctionnent les magasins de vecteurs

Les magasins de vecteurs Rememberizer convertissent le texte en représentations vectorielles de haute dimension (embeddings) qui capturent le sens sémantique. Cela permet :

  1. Recherche sémantique : Trouver des documents en fonction du sens plutôt que des mots-clés

  2. Correspondance de similarité : Identifier du contenu conceptuellement lié

  3. Récupération efficace : Localiser rapidement des informations pertinentes à partir de grands ensembles de données

Composants Clés

  • Traitement de Document : Le texte est divisé en morceaux de taille optimale avec des frontières qui se chevauchent pour préserver le contexte

  • Vectorisation : Les morceaux sont convertis en embeddings à l'aide de modèles à la pointe de la technologie

  • Indexation : Des algorithmes spécialisés organisent les vecteurs pour une recherche de similarité efficace

  • Traitement de Requête : Les requêtes de recherche sont vectorisées et comparées aux embeddings stockés

Architecture

Rememberizer implémente des magasins de vecteurs en utilisant :

  • PostgreSQL avec l'extension pgvector : Pour un stockage et une recherche de vecteurs efficaces

  • Organisation basée sur des collections : Chaque magasin de vecteurs a sa propre collection isolée

  • Accès piloté par API : Points de terminaison RESTful simples pour toutes les opérations

Commencer

Création d'un Magasin de Vecteurs

  1. Accédez à la section Magasins de Vecteurs dans votre tableau de bord

  2. Cliquez sur "Créer un nouveau Magasin de Vecteurs" :

    • Un formulaire apparaîtra vous demandant d'entrer des détails.

  3. Remplissez les Détails :

    • Nom : Fournissez un nom unique pour votre magasin de vecteurs.

    • Description : Écrivez une brève description du magasin de vecteurs.

    • Modèle d'Incorporation : Sélectionnez le modèle qui convertit le texte en vecteurs.

    • Algorithme d'Indexation : Choisissez comment les vecteurs seront organisés pour la recherche.

    • Métrique de Recherche : Définissez comment la similarité entre les vecteurs est calculée.

    • Dimension du Vecteur : La taille des incorporations de vecteurs (généralement 768-1536).

  4. Soumettez le Formulaire :

    • Cliquez sur le bouton "Créer". Vous recevrez une notification de succès, et le nouveau magasin apparaîtra dans votre liste de magasins de vecteurs.

Options de configuration

Modèles d'Intégration

Modèle
Dimensions
Description
Meilleur Pour

openai/text-embedding-3-large

1536

Modèle d'intégration à haute précision d'OpenAI

Applications de production nécessitant une précision maximale

openai/text-embedding-3-small

1536

Modèle d'intégration plus petit et plus rapide d'OpenAI

Applications avec des exigences de débit plus élevées

Algorithmes d'indexation

Algorithme
Description
Compromis

IVFFLAT (par défaut)

Fichier inversé avec compression plate

Bon équilibre entre vitesse et précision ; fonctionne bien pour la plupart des ensembles de données

HNSW

Petit monde navigable hiérarchique

Meilleure précision pour les grands ensembles de données ; exigences de mémoire plus élevées

Métriques de recherche

Métrique
Description
Meilleur pour

cosinus (par défaut)

Mesure l'angle entre les vecteurs

Correspondance de similarité à usage général

produit scalaire (ip)

Produit scalaire entre les vecteurs

Lorsque la magnitude du vecteur est importante

L2 (Euclidien)

Distance en ligne droite entre les vecteurs

Lorsque les relations spatiales sont importantes

Gestion des Magasins de Vecteurs

  1. Voir et Éditer les Magasins de Vecteurs :

    • Accédez au tableau de bord de gestion pour voir, éditer ou supprimer des magasins de vecteurs.

  2. Visualisation des Documents :

    • Parcourez les documents individuels et leurs métadonnées associées au sein d'un magasin de vecteurs spécifique.

  3. Statistiques :

    • Consultez des statistiques détaillées telles que le nombre de vecteurs stockés, les performances des requêtes et les métriques opérationnelles.

Gestion des clés API

Les clés API sont utilisées pour authentifier et autoriser l'accès aux points de terminaison de l'API du magasin de vecteurs Rememberizer. Une gestion appropriée des clés API est essentielle pour maintenir la sécurité et l'intégrité de vos magasins de vecteurs.

Création de Clés API

  1. Rendez-vous sur la page de détails de votre Vector Store

  2. Naviguez vers la section de Gestion des Clés API :

    • Elle se trouve dans l'onglet "Configuration"

  3. Cliquez sur "Ajouter une Clé API" :

    • Un formulaire apparaîtra vous demandant d'entrer des détails.

  4. Remplissez les Détails :

    • Nom : Fournissez un nom pour la clé API afin de vous aider à identifier son cas d'utilisation.

  5. Soumettez le Formulaire :

    • Cliquez sur le bouton "Créer". La nouvelle clé API sera générée et affichée. Assurez-vous de la copier et de la stocker en toute sécurité. Cette clé est utilisée pour authentifier les demandes à ce vector store spécifique.

Révocation des clés API

Si une clé API n'est plus nécessaire, vous pouvez la supprimer pour éviter tout usage abusif potentiel.

Pour des raisons de sécurité, vous voudrez peut-être faire tourner vos clés API périodiquement. Cela implique de générer une nouvelle clé et de révoquer l'ancienne.

Utilisation de l'API Vector Store

Après avoir créé un Vector Store et généré une clé API, vous pouvez interagir avec lui en utilisant l'API REST.

Exemples de Code

import requests
import json

API_KEY = "your_api_key_here"
VECTOR_STORE_ID = "vs_abc123"  # Remplacez par l'ID de votre magasin de vecteurs
BASE_URL = "https://api.rememberizer.ai/api/v1"

Télécharger un document dans le magasin de vecteurs

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"Document '{document_name}' téléchargé avec succès !")
        return response.json()
    else:
        print(f"Erreur lors du téléchargement du document : {response.text}")
        return None

Télécharger le contenu textuel vers le magasin de vecteurs

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"Document texte '{document_name}' téléchargé avec succès !")
    return response.json()
else:
    print(f"Erreur lors du téléchargement du texte : {response.text}")
    return None

Rechercher dans le magasin de vecteurs

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"Trouvé {len(results['matched_chunks'])} correspondances pour '{query}'")
    
    # Imprimer le meilleur résultat
    if results['matched_chunks']:
        top_match = results['matched_chunks'][0]
        print(f"Meilleure correspondance (distance : {top_match['distance']}):")
        print(f"Document : {top_match['document']['name']}")
        print(f"Contenu : {top_match['matched_content']}")
    
    return results
else:
    print(f"Erreur lors de la recherche : {response.text}")
    return None

Exemple d'utilisation

télécharger_document("path/to/document.pdf")

upload_text("Ceci est un texte d'exemple à vectoriser", "sample-document.txt")

search_vector_store("Comment fonctionne la similarité vectorielle ?")


</div>

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

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

  // Obtenir des informations sur le magasin de vecteurs
  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(`Échec de l'obtention des informations sur le magasin de vecteurs : ${response.statusText}`);
    }
    
    return response.json();
  }

  // Télécharger un document texte
  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(`Échec du téléchargement du document texte : ${response.statusText}`);
    }
    
    return response.json();
  }

  // Télécharger un fichier
  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(`Échec du téléchargement du fichier : ${xhr.statusText}`));
        }
      };
      
      xhr.onerror = () => {
        reject(new Error('Erreur réseau lors du téléchargement du fichier'));
      };
      
      xhr.send(formData);
    });
  }

  // Rechercher des documents dans le magasin de vecteurs
  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(`Échec de la recherche : ${response.statusText}`);
    }
    
    return response.json();
  }

  // Lister tous les documents dans le magasin de vecteurs
  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(`Échec de la liste des documents : ${response.statusText}`);
    }
    
    return response.json();
  }

  // Supprimer un document
  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(`Échec de la suppression du document : ${response.statusText}`);
    }
    
    return true;
  }
}

// Exemple d'utilisation
/*
const client = new VectorStoreClient('your_api_key', 'vs_abc123');

// Rechercher des documents
client.searchDocuments('Comment fonctionne la recherche sémantique ?')
  .then(results => {
    console.log(`Trouvé ${results.matched_chunks.length} correspondances`);
    results.matched_chunks.forEach(match => {
      console.log(`Document : ${match.document.name}`);
      console.log(`Score : ${match.distance}`);
      console.log(`Contenu : ${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

  # Obtenir les détails du magasin de vecteurs
  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

  # Télécharger du contenu texte
  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

  # Rechercher des documents
  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

  # Lister les documents
  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

  # Télécharger un fichier (formulaire multipart)
  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 "La demande API a échoué : #{response.code} #{response.message}\n#{response.body}"
    end
    
    response
  end
end

Exemple d'utilisation

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

Rechercher des documents

results = client.search('Quelles sont les meilleures pratiques en matière de sécurité des données ?') puts "Trouvé #{results['matched_chunks'].length} résultats"

Afficher le meilleur résultat

if results['matched_chunks'].any? top_match = results['matched_chunks'].first puts "Meilleur match (distance : #{top_match['distance']}):" puts "Document : #{top_match['document']['name']}" puts "Contenu : #{top_match['matched_content']}" end =end


</div>

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

```bash
# Définissez votre clé API et l'ID du magasin de vecteurs
API_KEY="your_api_key_here"
VECTOR_STORE_ID="vs_abc123"
BASE_URL="https://api.rememberizer.ai/api/v1"

# Obtenir des informations sur le magasin de vecteurs
curl -X GET "${BASE_URL}/vector-stores/${VECTOR_STORE_ID}" \
  -H "x-api-key: ${API_KEY}"

# Télécharger un document texte
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": "Ceci est un document d'exemple qui sera vectorisé et stocké dans la base de données vectorielle pour la recherche sémantique."
  }'

# Télécharger un fichier
curl -X POST "${BASE_URL}/vector-stores/${VECTOR_STORE_ID}/documents" \
  -H "x-api-key: ${API_KEY}" \
  -F "file=@/path/to/your/document.pdf"

# Rechercher des documents
curl -X GET "${BASE_URL}/vector-stores/${VECTOR_STORE_ID}/documents/search?q=semantic%20search&n=5&prev_chunks=1&next_chunks=1" \
  -H "x-api-key: ${API_KEY}"

# Lister tous les documents
curl -X GET "${BASE_URL}/vector-stores/${VECTOR_STORE_ID}/documents" \
  -H "x-api-key: ${API_KEY}"

# Supprimer un document
curl -X DELETE "${BASE_URL}/vector-stores/${VECTOR_STORE_ID}/documents/123" \
  -H "x-api-key: ${API_KEY}"

Considérations de Performance

À venir : Diagramme d'Architecture du Vector Store

Ce diagramme d'architecture technique illustrera :

  • L'architecture de base PostgreSQL + pgvector

  • Structures des algorithmes d'indexation (IVFFLAT vs. HNSW)

  • Comment fonctionnent les métriques de recherche dans l'espace vectoriel (comparaison visuelle)

  • Processus de découpage de documents avec visualisation de chevauchement

  • Considérations de performance visualisées à différentes échelles

Optimisation pour Différents Volumes de Données

Volume de Données
Configuration Recommandée
Remarques

Petit (<10k documents)

IVFFLAT, similarité cosinus

Configuration simple offrant de bonnes performances

Moyen (10k-100k documents)

IVFFLAT, assurer un réindexage régulier

Équilibre entre la vitesse de recherche et la maintenance de l'index

Grand (>100k documents)

HNSW, envisager d'augmenter les dimensions des vecteurs

Utilisation de mémoire plus élevée mais maintient les performances à grande échelle

Stratégies de découpage

Le processus de découpage impacte significativement la qualité de recherche :

  • Taille de Chunk : Rememberizer utilise une taille de chunk par défaut de 1024 octets avec un chevauchement de 200 octets

  • Chunks Plus Petits (512-1024 octets) : Correspondances plus précises, mieux pour des questions spécifiques

  • Chunks Plus Grands (1500-2048 octets) : Plus de contexte dans chaque correspondance, mieux pour des sujets plus larges

  • Chevauchement : Assure que le contexte n'est pas perdu aux limites des chunks

Optimisation des Requêtes

  • Fenêtres de Contexte : Utilisez prev_chunks et next_chunks pour récupérer le contenu environnant

  • Nombre de Résultats : Commencez avec 3-5 résultats (paramètre n) et ajustez en fonction des besoins de précision

  • Seuil : Ajustez le paramètre t pour filtrer les résultats par score de similarité

Utilisation Avancée

Réindexation

Rememberizer déclenche automatiquement la réindexation lorsque le nombre de vecteurs dépasse des seuils prédéfinis, mais envisagez une réindexation manuelle après :

  • Avoir téléchargé un grand nombre de documents

  • Avoir changé le modèle d'incorporation

  • Avoir modifié l'algorithme d'indexation

Amélioration des requêtes

Pour de meilleurs résultats de recherche :

  1. Soyez spécifique dans les requêtes de recherche

  2. Incluez le contexte lorsque c'est possible

  3. Utilisez un langage naturel plutôt que des mots-clés

  4. Ajustez les paramètres en fonction de la qualité des résultats

Migration depuis d'autres bases de données vectorielles

Si vous utilisez actuellement d'autres solutions de bases de données vectorielles et souhaitez migrer vers Rememberizer Vector Store, les guides suivants vous aideront à transférer vos données efficacement.

Vue d'ensemble de la migration

La migration des données vectorielles implique :

  1. L'exportation des données de votre base de données vectorielle source

  2. La conversion des données dans un format compatible avec Rememberizer

  3. L'importation des données dans votre magasin de vecteurs Rememberizer

  4. La vérification que la migration a réussi

Avantages de la migration vers Rememberizer

  • Fondation PostgreSQL : Construit sur une technologie de base de données mature avec sauvegarde et récupération intégrées

  • Écosystème intégré : Connexion transparente avec d'autres composants de Rememberizer

  • Gestion simplifiée : Interface unifiée pour les opérations vectorielles

  • Sécurité avancée : Sécurité au niveau des lignes et contrôles d'accès granulaires

  • Architecture évolutive : Optimisation des performances à mesure que vos données croissent

Migration de Pinecone

import os
import pinecone
import requests
import json
import time

# Configurer le client Pinecone
pinecone.init(api_key="PINECONE_API_KEY", environment="PINECONE_ENV")
source_index = pinecone.Index("your-pinecone-index")

# Configurer le client de la boutique de vecteurs Rememberizer
REMEMBERIZER_API_KEY = "your_rememberizer_api_key"
VECTOR_STORE_ID = "vs_abc123"  # Votre ID de boutique de vecteurs Rememberizer
BASE_URL = "https://api.rememberizer.ai/api/v1"

# 1. Configurer la taille du lot pour la migration (ajuster en fonction de la taille de vos données)
BATCH_SIZE = 100

# 2. Fonction pour obtenir des vecteurs de Pinecone
def fetch_vectors_from_pinecone(index_name, batch_size, cursor=None):
    # Utilisez l'opération de liste si disponible dans votre version de Pinecone
    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:
        # Pour les anciennes versions de Pinecone sans opération de liste
        # Il s'agit d'une approche simplifiée ; l'implémentation réelle dépend de votre modèle d'accès aux données
        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. Fonction pour télécharger des vecteurs vers 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():
        # Convertir les données de vecteur Pinecone au format Rememberizer
        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"Passage de {vector_id} - aucun contenu textuel trouvé dans les métadonnées")
            continue
            
        data = {
            "name": document_name,
            "content": content,
            # Optionnel : inclure des métadonnées supplémentaires
            "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"Document '{document_name}' téléchargé avec succès !")
        else:
            print(f"Erreur lors du téléchargement du document {document_name} : {response.text}")
        
        # Ajouter un petit délai pour éviter la limitation de débit
        time.sleep(0.1)

# 4. Fonction principale de migration
def migrate_pinecone_to_rememberizer():
    cursor = None
    total_migrated = 0
    
    print("Démarrage de la migration de Pinecone vers Rememberizer...")
    
    while True:
        vectors, cursor = fetch_vectors_from_pinecone("your-pinecone-index", BATCH_SIZE, cursor)
        
        if not vectors:
            break
            
        print(f"Récupéré {len(vectors)} vecteurs de Pinecone")
        upload_to_rememberizer(vectors)
        
        total_migrated += len(vectors)
        print(f"Progression : {total_migrated} vecteurs migrés")
        
        if not cursor:
            break
    
    print(f"Migration terminée ! {total_migrated} vecteurs au total migrés vers Rememberizer")

# Exécutez la migration
# migrer_pinecone_vers_rememberizer()
const { PineconeClient } = require('@pinecone-database/pinecone');
const axios = require('axios');

// Configuration de Pinecone
const pineconeApiKey = 'PINECONE_API_KEY';
const pineconeEnvironment = 'PINECONE_ENVIRONMENT';
const pineconeIndexName = 'YOUR_PINECONE_INDEX';

// Configuration de Rememberizer
const rememberizerApiKey = 'YOUR_REMEMBERIZER_API_KEY';
const vectorStoreId = 'vs_abc123';
const baseUrl = 'https://api.rememberizer.ai/api/v1';

// Configuration de la taille du lot
const BATCH_SIZE = 100;

// Initialiser le client Pinecone
async function initPinecone() {
  const pinecone = new PineconeClient();
  await pinecone.init({
    apiKey: pineconeApiKey,
    environment: pineconeEnvironment,
  });
  return pinecone;
}

// Récupérer les vecteurs depuis Pinecone
async function fetchVectorsFromPinecone(pinecone, batchSize, paginationToken = null) {
  const index = pinecone.Index(pineconeIndexName);
  
  try {
    // Pour les versions plus récentes de Pinecone
    const listResponse = await index.list({
      limit: batchSize,
      paginationToken: paginationToken
    });
    
    return {
      vectors: listResponse.vectors || {},
      nextToken: listResponse.paginationToken
    };
  } catch (error) {
    // Solution de secours pour les versions plus anciennes de Pinecone
    // Ceci est simplifié ; l'implémentation réelle dépend de votre modèle d'accès aux données
    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 };
  }
}

// Télécharger les vecteurs vers Rememberizer
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(`Ignorer ${vectorId} - aucun contenu textuel trouvé dans les métadonnées`);
      continue;
    }
    
    const data = {
      name: documentName,
      content: content,
      // Optionnel : inclure des métadonnées supplémentaires
      metadata: vectorData.metadata || {}
    };
    
    try {
      const response = await axios.post(
        `${baseUrl}/vector-stores/${vectorStoreId}/documents/text`,
        data,
        { headers }
      );
      
      if (response.status === 201) {
        console.log(`Document '${documentName}' téléchargé avec succès !`);
        results.push({ id: vectorId, success: true });
      } else {
        console.error(`Erreur lors du téléchargement du document ${documentName} : ${response.statusText}`);
        results.push({ id: vectorId, success: false, error: response.statusText });
      }
    } catch (error) {
      console.error(`Erreur lors du téléchargement du document ${documentName} : ${error.message}`);
      results.push({ id: vectorId, success: false, error: error.message });
    }
    
    // Ajouter un petit délai pour éviter la limitation de débit
    await new Promise(resolve => setTimeout(resolve, 100));
  }
  
  return results;
}

// Fonction principale de migration
async function migratePineconeToRememberizer() {
  try {
    console.log('Démarrage de la migration de Pinecone vers Rememberizer...');
    
    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(`Récupéré ${Object.keys(vectors).length} vecteurs depuis Pinecone`);
      
      const results = await uploadToRememberizer(vectors);
      const successCount = results.filter(r => r.success).length;
      
      totalMigrated += successCount;
      console.log(`Progression : ${totalMigrated} vecteurs migrés avec succès`);
      
    } while (nextToken);
    
    console.log(`Migration terminée ! ${totalMigrated} vecteurs au total migrés vers Rememberizer`);
    
  } catch (error) {
    console.error('Échec de la migration :', error);
  }
}

// Exécuter la migration
// migratePineconeToRememberizer();

Migration de Qdrant

import requests
import json
import time
from qdrant_client import QdrantClient
from qdrant_client.http import models as rest

# Configurer le client Qdrant
QDRANT_URL = "http://localhost:6333"  # ou votre URL Qdrant cloud
QDRANT_API_KEY = "your_qdrant_api_key"  # si vous utilisez Qdrant Cloud
QDRANT_COLLECTION_NAME = "your_collection"

qdrant_client = QdrantClient(
    url=QDRANT_URL,
    api_key=QDRANT_API_KEY  # Seulement pour Qdrant Cloud
)

# Configurer le client de la boutique de vecteurs Rememberizer
REMEMBERIZER_API_KEY = "your_rememberizer_api_key"
VECTOR_STORE_ID = "vs_abc123"  # Votre ID de boutique de vecteurs Rememberizer
BASE_URL = "https://api.rememberizer.ai/api/v1"

# Taille du lot pour le traitement
BATCH_SIZE = 100

# Fonction pour récupérer des points depuis Qdrant
def fetch_points_from_qdrant(collection_name, batch_size, offset=0):
    try:
        # Obtenir des informations sur la collection pour déterminer la dimension du vecteur
        collection_info = qdrant_client.get_collection(collection_name=collection_name)
        
        # Faire défiler les points
        scroll_result = qdrant_client.scroll(
            collection_name=collection_name,
            limit=batch_size,
            offset=offset,
            with_payload=True,
            with_vectors=True
        )
        
        points = scroll_result[0]  # Tuple de (points, next_offset)
        next_offset = scroll_result[1]
        
        return points, next_offset
    except Exception as e:
        print(f"Erreur lors de la récupération des points depuis Qdrant : {e}")
        return [], None

# Fonction pour télécharger des vecteurs vers Rememberizer
def upload_to_rememberizer(points):
    headers = {
        "x-api-key": REMEMBERIZER_API_KEY,
        "Content-Type": "application/json"
    }
    
    results = []
    
    for point in points:
        # Extraire les données du point Qdrant
        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"Saut de {point_id} - aucun contenu textuel trouvé dans la charge utile")
            continue
            
        data = {
            "name": document_name,
            "content": text_content,
            # Optionnel : inclure des métadonnées supplémentaires
            "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"Document '{document_name}' téléchargé avec succès !")
                results.append({"id": point_id, "success": True})
            else:
                print(f"Erreur lors du téléchargement du document {document_name} : {response.text}")
                results.append({"id": point_id, "success": False, "error": response.text})
        except Exception as e:
            print(f"Exception lors du téléchargement du document {document_name} : {str(e)}")
            results.append({"id": point_id, "success": False, "error": str(e)})
        
        # Ajouter un petit délai pour éviter la limitation de débit
        time.sleep(0.1)
    
    return results

# Fonction principale de migration
def migrate_qdrant_to_rememberizer():
    offset = None
    total_migrated = 0
    
    print("Démarrage de la migration de Qdrant vers Rememberizer...")
    
    while True:
        points, next_offset = fetch_points_from_qdrant(
            QDRANT_COLLECTION_NAME, 
            BATCH_SIZE,
            offset
        )
        
        if not points:
            break
            
        print(f"Récupéré {len(points)} points de Qdrant")
        
        results = upload_to_rememberizer(points)
        success_count = sum(1 for r in results if r.get("success", False))
        
        total_migrated += success_count
        print(f"Progression : {total_migrated} points migrés avec succès")
        
        if next_offset is None:
            break
            
        offset = next_offset
    
    print(f"Migrazione terminée ! {total_migrated} points au total migrés vers Rememberizer")

# Exécutez la migration
# migrate_qdrant_to_rememberizer()
const { QdrantClient } = require('@qdrant/js-client-rest');
const axios = require('axios');

// Configuration de Qdrant
const qdrantUrl = 'http://localhost:6333'; // ou votre URL cloud Qdrant
const qdrantApiKey = 'your_qdrant_api_key'; // si vous utilisez Qdrant Cloud
const qdrantCollectionName = 'your_collection';

// Configuration de Rememberizer
const rememberizerApiKey = 'YOUR_REMEMBERIZER_API_KEY';
const vectorStoreId = 'vs_abc123';
const baseUrl = 'https://api.rememberizer.ai/api/v1';

// Configuration de la taille du lot
const BATCH_SIZE = 100;

// Initialiser le client Qdrant
const qdrantClient = new QdrantClient({ 
  url: qdrantUrl,
  apiKey: qdrantApiKey // Seulement pour Qdrant Cloud
});

// Récupérer des points depuis Qdrant
async function fetchPointsFromQdrant(collectionName, batchSize, offset = 0) {
  try {
    // Obtenir les informations de la collection
    const collectionInfo = await qdrantClient.getCollection(collectionName);
    
    // Faire défiler les points
    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(`Erreur lors de la récupération des points depuis Qdrant : ${error.message}`);
    return { points: [], nextOffset: null };
  }
}

// Télécharger des vecteurs vers Rememberizer
async function uploadToRememberizer(points) {
  const headers = {
    'x-api-key': rememberizerApiKey,
    'Content-Type': 'application/json'
  };
  
  const results = [];
  
  for (const point of points) {
    // Extraire les données du point Qdrant
    const pointId = point.id;
    const metadata = point.payload || {};
    const textContent = metadata.text || '';
    const documentName = metadata.filename || `qdrant_doc_${pointId}`;
    
    if (!textContent) {
      console.log(`Ignorer ${pointId} - aucun contenu texte trouvé dans la charge utile`);
      continue;
    }
    
    const data = {
      name: documentName,
      content: textContent,
      // Optionnel : inclure des métadonnées supplémentaires
      metadata: metadata
    };
    
    try {
      const response = await axios.post(
        `${baseUrl}/vector-stores/${vectorStoreId}/documents/text`,
        data,
        { headers }
      );
      
      if (response.status === 201) {
        console.log(`Document '${documentName}' téléchargé avec succès !`);
        results.push({ id: pointId, success: true });
      } else {
        console.error(`Erreur lors du téléchargement du document ${documentName} : ${response.statusText}`);
        results.push({ id: pointId, success: false, error: response.statusText });
      }
    } catch (error) {
      console.error(`Erreur lors du téléchargement du document ${documentName} : ${error.message}`);
      results.push({ id: pointId, success: false, error: error.message });
    }
    
    // Ajouter un petit délai pour éviter la limitation de débit
    await new Promise(resolve => setTimeout(resolve, 100));
  }
  
  return results;
}

// Fonction principale de migration
async function migrateQdrantToRememberizer() {
  try {
    console.log('Démarrage de la migration de Qdrant vers Rememberizer...');
    
    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(`Récupéré ${points.length} points depuis Qdrant`);
      
      const results = await uploadToRememberizer(points);
      const successCount = results.filter(r => r.success).length;
      
      totalMigrated += successCount;
      console.log(`Progression : ${totalMigrated} points migrés avec succès`);
      
    } while (offset !== null);
    
    console.log(`Migration terminée ! ${totalMigrated} points au total migrés vers Rememberizer`);
    
  } catch (error) {
    console.error('Échec de la migration :', error);
  }
}

// Exécuter la migration
// migrateQdrantToRememberizer();

Migration de Supabase pgvector

Si vous utilisez déjà Supabase avec pgvector, la migration vers Rememberizer est particulièrement simple puisque les deux utilisent PostgreSQL avec l'extension pgvector.

import psycopg2
import requests
import json
import time
import os
from dotenv import load_dotenv

# Charger les variables d'environnement
load_dotenv()

# Configuration PostgreSQL de Supabase
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")

# Configuration de Rememberizer
REMEMBERIZER_API_KEY = os.getenv("REMEMBERIZER_API_KEY")
VECTOR_STORE_ID = os.getenv("VECTOR_STORE_ID")  # par exemple, "vs_abc123"
BASE_URL = "https://api.rememberizer.ai/api/v1"

# Taille du lot pour le traitement
BATCH_SIZE = 100

# Se connecter à Supabase PostgreSQL
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"Erreur de connexion à Supabase PostgreSQL : {e}")
        return None

# Récupérer des documents depuis Supabase pgvector
def fetch_documents_from_supabase(conn, batch_size, offset=0):
    try:
        cursor = conn.cursor()
        
        # Ajustez cette requête en fonction de la structure de votre table
        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"Erreur lors de la récupération des documents depuis Supabase : {e}")
        return []

# Télécharger des documents sur Rememberizer
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
        
        # Analyser les métadonnées si elles sont stockées sous forme de chaîne JSON
        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"Passer {doc_id} - aucun contenu trouvé")
            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"Document '{document_name}' téléchargé avec succès !")
                results.append({"id": doc_id, "success": True})
            else:
                print(f"Erreur lors du téléchargement du document {document_name} : {response.text}")
                results.append({"id": doc_id, "success": False, "error": response.text})
        except Exception as e:
            print(f"Exception lors du téléchargement du document {document_name} : {str(e)}")
            results.append({"id": doc_id, "success": False, "error": str(e)})
        
        # Ajouter un petit délai pour éviter la limitation de débit
        time.sleep(0.1)
    
    return results

# Fonction principale de migration
def migrate_supabase_to_rememberizer():
    conn = connect_to_supabase()
    if not conn:
        print("Échec de la connexion à Supabase. Abandon de la migration.")
        return
    
    offset = 0
    total_migrated = 0
    
    print("Démarrage de la migration de Supabase pgvector vers Rememberizer...")
    
    try:
        while True:
            documents = fetch_documents_from_supabase(conn, BATCH_SIZE, offset)
            
            if not documents:
                break
                
            print(f"Récupéré {len(documents)} documents de Supabase")
            
            results = upload_to_rememberizer(documents)
            success_count = sum(1 for r in results if r.get("success", False))
            
            total_migrated += success_count
            print(f"Progression : {total_migrated} documents migrés avec succès")
            
            offset += BATCH_SIZE
            
    finally:
        conn.close()
    
    print(f"Migration terminée ! {total_migrated} documents au total migrés vers Rememberizer")

# Exécutez la migration
# migrate_supabase_to_rememberizer()
const { Pool } = require('pg');
const axios = require('axios');
require('dotenv').config();

// Configuration PostgreSQL Supabase
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';

// Configuration Rememberizer
const rememberizerApiKey = process.env.REMEMBERIZER_API_KEY;
const vectorStoreId = process.env.VECTOR_STORE_ID; // e.g., "vs_abc123"
const baseUrl = 'https://api.rememberizer.ai/api/v1';

// Configuration de la taille du lot
const BATCH_SIZE = 100;

// Récupérer des documents depuis Supabase pgvector
async function fetchDocumentsFromSupabase(batchSize, offset = 0) {
  try {
    // Ajustez cette requête en fonction de la structure de votre table
    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(`Erreur lors de la récupération des documents depuis Supabase : ${error.message}`);
    return [];
  }
}

// Télécharger des documents vers Rememberizer
async function uploadToRememberizer(documents) {
  const headers = {
    'x-api-key': rememberizerApiKey,
    'Content-Type': 'application/json'
  };
  
  const results = [];
  
  for (const doc of documents) {
    // Analyser les métadonnées si elles sont stockées sous forme de chaîne JSON
    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(`Ignorer ${doc.id} - aucun contenu trouvé`);
      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(`Document '${documentName}' téléchargé avec succès !`);
        results.push({ id: doc.id, success: true });
      } else {
        console.error(`Erreur lors du téléchargement du document ${documentName} : ${response.statusText}`);
        results.push({ id: doc.id, success: false, error: response.statusText });
      }
    } catch (error) {
      console.error(`Erreur lors du téléchargement du document ${documentName} : ${error.message}`);
      results.push({ id: doc.id, success: false, error: error.message });
    }
    
    // Ajouter un petit délai pour éviter la limitation de débit
    await new Promise(resolve => setTimeout(resolve, 100));
  }
  
  return results;
}

// Fonction principale de migration
async function migrateSupabaseToRememberizer() {
  try {
    console.log('Démarrage de la migration de Supabase pgvector vers Rememberizer...');
    
    let offset = 0;
    let totalMigrated = 0;
    
    while (true) {
      const documents = await fetchDocumentsFromSupabase(BATCH_SIZE, offset);
      
      if (documents.length === 0) {
        break;
      }
      
      console.log(`Récupéré ${documents.length} documents depuis Supabase`);
      
      const results = await uploadToRememberizer(documents);
      const successCount = results.filter(r => r.success).length;
      
      totalMigrated += successCount;
      console.log(`Progression : ${totalMigrated} documents migrés avec succès`);
      
      offset += BATCH_SIZE;
    }
    
    console.log(`Migration terminée ! ${totalMigrated} documents au total migrés vers Rememberizer`);
    
  } catch (error) {
    console.error('La migration a échoué :', error);
  } finally {
    await supabasePool.end();
  }
}

// Exécuter la migration
// migrateSupabaseToRememberizer();

Meilleures Pratiques de Migration

Suivez ces recommandations pour une migration réussie :

  1. Planifiez à l'avance :

    • Estimez le volume de données et le temps requis pour la migration

    • Planifiez la migration pendant les périodes de faible trafic

    • Augmentez l'espace disque avant de commencer de grandes migrations

  2. Testez d'abord :

    • Créez un magasin de vecteurs de test dans Rememberizer

    • Migrez un petit sous-ensemble de données (100-1000 vecteurs)

    • Vérifiez la fonctionnalité de recherche avec des requêtes clés

  3. Validation des Données :

    • Comparez les comptes de documents avant et après la migration

    • Exécutez des requêtes de référence pour garantir des résultats similaires

    • Validez que les métadonnées sont correctement préservées

  4. Optimisez pour la Performance :

    • Utilisez des opérations par lots pour plus d'efficacité

    • Envisagez la colocation géographique des bases de données source et cible

    • Surveillez les limites de taux d'API et ajustez les tailles de lot en conséquence

  5. Étapes Post-Migration :

    • Vérifiez la création de l'index dans Rememberizer

    • Mettez à jour les configurations de l'application pour pointer vers le nouveau magasin de vecteurs

    • Gardez la base de données source en tant que sauvegarde jusqu'à ce que la migration soit vérifiée

Pour une référence API détaillée et la documentation des points de terminaison, visitez la page Documentation sur le stockage vectoriel.


Assurez-vous de gérer les clés API de manière sécurisée et de suivre les meilleures pratiques pour la gestion des clés API.

Qu'est-ce que les embeddings vectoriels et les bases de données vectorielles ?
Créer un Nouveau Magasin de Vecteurs
Voir les Détails d'un Magasin de Vecteurs
Créer une Nouvelle Clé API
Créer un Nouveau Magasin de Vecteurs
Voir les Détails d'un Magasin de Vecteurs
Créer une Nouvelle Clé API