Rememberizer Docs
サインインサインアップお問い合わせ
日本語
日本語
  • なぜ Rememberizer なのか?
  • 背景
    • ベクトル埋め込みとベクトルデータベースとは?
    • 用語集
    • 標準化された用語
  • 個人利用
    • はじめに
      • 知識を検索する
      • メメントフィルターアクセス
      • 一般的な知識
      • 埋め込まれた知識を管理する
  • インテグレーション
    • Rememberizer アプリ
    • Rememberizer Slack インテグレーション
    • Rememberizer Google Drive インテグレーション
    • Rememberizer Dropbox インテグレーション
    • Rememberizer Gmail インテグレーション
    • Rememberizer Memory インテグレーション
    • Rememberizer MCP サーバー
    • サードパーティアプリの管理
  • 開発者リソース
    • 開発者概要
  • 統合オプション
    • APIキーの登録と使用
    • Rememberizerアプリの登録
    • Rememberizerアプリの認証
    • Rememberizer GPTの作成
    • LangChain統合
    • ベクターストア
    • Slackとの対話サンプルWebアプリ
  • エンタープライズ統合
    • エンタープライズ統合パターン
  • APIリファレンス
    • APIドキュメントホーム
    • 認証
  • コアAPI
    • 意味的類似性によるドキュメントの検索
    • ドキュメントの取得
    • ドキュメントの内容を取得
    • Slackコンテンツの取得
    • Rememberizerにコンテンツを記憶する
  • アカウントと設定
    • 現在のユーザーアカウントの詳細を取得
    • 利用可能なデータソース統合の一覧
    • メメント
    • 追加されたすべての公開知識を取得
  • ベクターストアAPI
    • ベクターストアのドキュメント
    • ベクターストア情報を取得する
    • ベクターストア内のドキュメントのリストを取得する
    • ドキュメント情報を取得する
    • ベクターストアに新しいテキストドキュメントを追加する
    • ファイルをベクターストアにアップロードする
    • ベクターストア内のファイルコンテンツを更新する
    • ベクターストア内のドキュメントを削除する
    • 意味的類似性によるベクターストアドキュメントの検索
  • 追加リソース
    • 通知
      • 利用規約
      • プライバシーポリシー
      • B2B
        • Redditエージェントについて
  • リリース
    • リリースノートホーム
  • 2025年のリリース
    • 2025年4月25日
    • 2025年4月18日
    • 2025年4月11日
    • 2025年4月4日
    • 2025年3月28日
    • 2025年3月21日
    • 2025年3月14日
    • 2025年1月17日
  • 2024年のリリース
    • 2024年12月27日
    • 2024年12月20日
    • 2024年12月13日
    • 2024年12月6日
  • 2024年11月29日
  • 2024年11月22日
  • 2024年11月15日
  • 2024年11月8日
  • 2024年11月1日
  • 2024年10月25日
  • 2024年10月18日
  • 2024年10月11日
  • 2024年10月4日
  • 2024年9月27日
  • 2024年9月20日
  • 2024年9月13日
  • 2024年8月16日
  • 2024年8月9日
  • 2024年8月2日
  • 2024年7月26日
  • 2024年7月12日
  • 2024年6月28日
  • 2024年6月14日
  • 2024年5月31日
  • 2024年5月17日
  • 2024年5月10日
  • 2024年4月26日
  • 2024年4月19日
  • 2024年4月12日
  • 2024年4月5日
  • 2024年3月25日
  • 2024年3月18日
  • 2024年3月11日
  • 2024年3月4日
  • 2024年2月26日
  • 2024年2月19日
  • 2024年2月12日
  • 2024年2月5日
  • 2024年1月29日
  • 2024年1月22日
  • 2024年1月15日
  • LLM ドキュメント
    • Rememberizer LLM レディ ドキュメント
Powered by GitBook
On this page
  • はじめに
  • 技術概要
  • ベクトルストアの仕組み
  • 主要コンポーネント
  • アーキテクチャ
  • 始めに
  • ベクトルストアの作成
  • 設定オプション
  • ベクトルストアの管理
  • APIキー管理
  • APIキーの作成
  • APIキーの取り消し
  • ベクトルストアAPIの使用
  • コード例
  • パフォーマンスの考慮事項
  • 異なるデータ量の最適化
  • チャンク戦略
  • クエリ最適化
  • 高度な使用法
  • 再インデックス作成
  • クエリの強化
  • 他のベクターデータベースからの移行
  • 移行の概要
  • Rememberizerへの移行の利点
  • Pineconeからの移行
  • Qdrantからの移行
  • Supabase pgvectorからの移行
  • 移行のベストプラクティス
  1. 統合オプション

ベクターストア

このガイドは、開発者としてRememberizerベクターストアを使用する方法を理解するのに役立ちます。

PreviousLangChain統合NextSlackとの対話サンプルWebアプリ

Last updated 1 month ago

Rememberizer ベクターストアは、ベクターデータの取り扱いを簡素化し、テキスト入力に集中できるようにし、検索やデータ分析などのさまざまなアプリケーションのためにベクターの力を活用します。

はじめに

Rememberizer Vector Storeは、ベクトルデータを扱うための使いやすいインターフェースを提供し、ベクトル埋め込みの複雑さを抽象化します。pgvector拡張機能を備えたPostgreSQLによって支えられたRememberizer Vector Storeは、テキストを直接操作することを可能にします。このサービスは、テキストデータのチャンク化、ベクトル化、保存を処理し、コアアプリケーションロジックに集中できるようにします。

ベクトル埋め込みとベクトルデータベースの背後にある理論的概念をより深く理解するには、をご覧ください。

技術概要

ベクトルストアの仕組み

Rememberizer ベクトルストアは、テキストを高次元のベクトル表現(埋め込み)に変換し、意味的な意味を捉えます。これにより、以下が可能になります:

  1. 意味検索:キーワードだけでなく、意味に基づいて文書を見つける

  2. 類似性マッチング:概念的に関連するコンテンツを特定する

  3. 効率的な取得:大規模データセットから関連情報を迅速に見つける

主要コンポーネント

  • ドキュメント処理: テキストは、コンテキストを保持するために重複する境界を持つ最適なサイズのチャンクに分割されます

  • ベクトル化: チャンクは、最先端のモデルを使用して埋め込みに変換されます

  • インデックス作成: 専門的なアルゴリズムがベクトルを整理し、効率的な類似検索を実現します

  • クエリ処理: 検索クエリはベクトル化され、保存された埋め込みと比較されます

アーキテクチャ

Rememberizerは、次の方法でベクターストアを実装しています:

  • pgvector拡張を使用したPostgreSQL:効率的なベクターの保存と検索のため

  • コレクションベースの組織:各ベクターストアは独自の孤立したコレクションを持つ

  • API駆動のアクセス:すべての操作のためのシンプルなRESTfulエンドポイント

始めに

ベクトルストアの作成

  1. ダッシュボードのベクトルストアセクションに移動します

  2. 「新しいベクトルストアを作成」をクリックします:

    • 詳細を入力するように促すフォームが表示されます。

  3. 詳細を入力します:

    • 名前:ベクトルストアのユニークな名前を提供します。

    • 説明:ベクトルストアの簡単な説明を書きます。

    • 埋め込みモデル:テキストをベクトルに変換するモデルを選択します。

    • インデックスアルゴリズム:ベクトルが検索のためにどのように整理されるかを選択します。

    • 検索メトリック:ベクトル間の類似性がどのように計算されるかを定義します。

    • ベクトル次元:ベクトル埋め込みのサイズ(通常は768-1536)。

  4. フォームを送信します:

    • 「作成」ボタンをクリックします。成功通知が届き、新しいストアがベクトルストアリストに表示されます。

設定オプション

埋め込みモデル

モデル
次元
説明
最適

openai/text-embedding-3-large

1536

OpenAIの高精度埋め込みモデル

最大の精度を必要とするプロダクションアプリケーション

openai/text-embedding-3-small

1536

OpenAIのより小さく、より高速な埋め込みモデル

より高いスループット要件を持つアプリケーション

インデクシングアルゴリズム

アルゴリズム
説明
トレードオフ

IVFFLAT (デフォルト)

フラット圧縮の逆ファイル

スピードと精度の良いバランス; ほとんどのデータセットでうまく機能

HNSW

階層的ナビゲーション可能なスモールワールド

大規模データセットに対してより良い精度; より高いメモリ要件

検索メトリクス

メトリック
説明
最適

コサイン (デフォルト)

ベクトル間の角度を測定

一般的な類似性マッチング

内積 (ip)

ベクトル間のドット積

ベクトルの大きさが重要な場合

L2 (ユークリッド)

ベクトル間の直線距離

空間的関係が重要な場合

ベクトルストアの管理

  1. ベクトルストアの表示と編集:

    • 管理ダッシュボードにアクセスして、ベクトルストアを表示、編集、または削除します。

  2. ドキュメントの表示:

    • 特定のベクトルストア内の個々のドキュメントとその関連メタデータを閲覧します。

  3. 統計:

    • 保存されたベクトルの数、クエリパフォーマンス、運用指標などの詳細な統計を表示します。

APIキー管理

APIキーは、RememberizerベクターストアのAPIエンドポイントへのアクセスを認証および承認するために使用されます。APIキーの適切な管理は、ベクターストアのセキュリティと整合性を維持するために不可欠です。

APIキーの作成

  1. ベクターストアの詳細ページに移動します

  2. APIキー管理セクションに移動します:

    • 「設定」タブ内にあります

  3. **「APIキーを追加」**をクリックします:

    • 詳細を入力するように促すフォームが表示されます。

  4. 詳細を入力します:

    • 名前: APIキーの使用ケースを特定するための名前を提供します。

  5. フォームを送信します:

    • 「作成」ボタンをクリックします。新しいAPIキーが生成され、表示されます。必ずコピーして安全に保管してください。このキーは、その特定のベクターストアへのリクエストを認証するために使用されます。

APIキーの取り消し

APIキーがもはや必要ない場合は、潜在的な悪用を防ぐために削除できます。

セキュリティ上の理由から、APIキーを定期的にローテーションすることをお勧めします。これは、新しいキーを生成し、古いキーを取り消すことを含みます。

ベクトルストアAPIの使用

ベクトルストアを作成し、APIキーを生成した後、REST APIを使用してそれと対話できます。

コード例

import requests
import json

API_KEY = "your_api_key_here"
VECTOR_STORE_ID = "vs_abc123"  # あなたのベクトルストアIDに置き換えてください
BASE_URL = "https://api.rememberizer.a

# ベクターストアにドキュメントをアップロードする
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_name}' が正常にアップロードされました!")
            return response.json()
        else:
            print(f"ドキュメントのアップロード中にエラーが発生しました: {response.text}")
            return None

# ベクトルストアにテキストコンテンツをアップロードする
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_name}' が正常にアップロードされました!")
        return response.json()
    else:
        print(f"テキストのアップロード中にエラーが発生しました: {response.text}")
        return None

# ベクトルストアを検索する
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"'{query}' に対して {len(results['matched_chunks'])} 件の一致が見つかりました")
        
        # 上位の結果を表示
        if results['matched_chunks']:
            top_match = results['matched_chunks'][0]
            print(f"上位の一致 (距離: {top_match['distance']}):")
            print(f"ドキュメント: {top_match['document']['name']}")
            print(f"内容: {top_match['matched_content']}")
        
        return results
    else:
        print(f"検索中にエラーが発生しました: {response.text}")
        return None

# 使用例
# ドキュメントをアップロードする("path/to/document.pdf")
# upload_text("これはベクトル化されるサンプルテキストです", "sample-document.txt")
# search_vector_store("ベクトル類似性はどのように機能しますか?")
// ベクトルストアAPIクライアント
class VectorStoreClient {
  constructor(apiKey, vectorStoreId) {
    this.apiKey = apiKey;
    this.vectorStoreId = vectorStoreId;
    this.baseUrl = 'https://api.rememberizer.ai/api/v1';
  }

  // ベクトルストア情報を取得
  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(`ベクトルストア情報の取得に失敗しました: ${response.statusText}`);
    }
    
    return response.json();
  }

  // テキストドキュメントをアップロード
  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(`テキストドキュメントのアップロードに失敗しました: ${response.statusText}`);
    }
    
    return response.json();
  }

  // ファイルをアップロード
  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(`ファイルのアップロードに失敗しました: ${xhr.statusText}`));
        }
      };
      
      xhr.onerror = () => {
        reject(new Error('ファイルアップロード中のネットワークエラー'));
      };
      
      xhr.send(formData);
    });
  }

  // ベクトルストア内のドキュメントを検索
  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(`検索に失敗しました: ${response.statusText}`);
    }
    
    return response.json();
  }

  // ベクトルストア内のすべてのドキュメントをリスト
  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(`ドキュメントのリストに失敗しました: ${response.statusText}`);
    }
    
    return response.json();
  }

  // ドキュメントを削除
  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(`ドキュメントの削除に失敗しました: ${response.statusText}`);
    }
    
    return true;
  }
}

// 使用例
/*
const client = new VectorStoreClient('your_api_key', 'vs_abc123');

// ドキュメントを検索
client.searchDocuments('セマンティック検索はどのように機能しますか?')
  .then(results => {
    console.log(`見つかったマッチ: ${results.matched_chunks.length}`);
    results.matched_chunks.forEach(match => {
      console.log(`ドキュメント: ${match.document.name}`);
      console.log(`スコア: ${match.distance}`);
      console.log(`内容: ${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

  # ベクトルストアの詳細を取得
  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

  # テキストコンテンツをアップロード
  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

  # ドキュメントを検索
  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

  # ドキュメントをリスト
  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

  # ファイルをアップロード(マルチパートフォーム)
  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リクエストに失敗しました: #{response.code} #{response.message}\n#{response.body}"
    end
    
    response
  end
end

使用例

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

ドキュメントを検索する

results = client.search('データセキュリティのベストプラクティスは何ですか?') puts "見つかった結果は #{results['matched_chunks'].length} 件です"

トップ結果を表示

if results['matched_chunks'].any? top_match = results['matched_chunks'].first puts "トップマッチ (距離: #{top_match['distance']}):" puts "ドキュメント: #{top_match['document']['name']}" puts "コンテンツ: #{top_match['matched_content']}" end =end


</div>

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

```bash
# APIキーとベクターストアIDを設定します
API_KEY="your_api_key_here"
VECTOR_STORE_ID="vs_abc123"
BASE_URL="https://api.rememberizer.ai/api/v1"

# ベクトルストア情報を取得
curl -X GET "${BASE_URL}/vector-stores/${VECTOR_STORE_ID}" \
  -H "x-api-key: ${API_KEY}"

# テキストドキュメントをアップロード
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": "これはベクトル化され、意味検索のためにベクトルデータベースに保存されるサンプルドキュメントです。"
  }'

# ファイルをアップロード
curl -X POST "${BASE_URL}/vector-stores/${VECTOR_STORE_ID}/documents" \
  -H "x-api-key: ${API_KEY}" \
  -F "file=@/path/to/your/document.pdf"

# ドキュメントを検索する
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}"

# すべてのドキュメントをリストする
curl -X GET "${BASE_URL}/vector-stores/${VECTOR_STORE_ID}/documents" \
  -H "x-api-key: ${API_KEY}"

# ドキュメントを削除する
curl -X DELETE "${BASE_URL}/vector-stores/${VECTOR_STORE_ID}/documents/123" \
  -H "x-api-key: ${API_KEY}"

パフォーマンスの考慮事項

近日公開: ベクトルストアアーキテクチャダイアグラム

この技術アーキテクチャダイアグラムは以下を示します:

  • PostgreSQL + pgvector 基盤アーキテクチャ

  • インデックスアルゴリズム構造 (IVFFLAT vs. HNSW)

  • ベクトル空間における検索メトリクスの動作 (視覚的比較)

  • オーバーラップの視覚化を伴うドキュメントチャンク処理

  • 異なるスケールで視覚化されたパフォーマンスの考慮事項

異なるデータ量の最適化

データ量
推奨構成
注釈

小 (<10k ドキュメント)

IVFFLAT, コサイン類似度

シンプルな構成で良好なパフォーマンスを提供

中 (10k-100k ドキュメント)

IVFFLAT, 定期的な再インデックスを確保

検索速度とインデックス維持のバランス

大 (>100k ドキュメント)

HNSW, ベクトル次元の増加を検討

メモリ使用量が増加するが、スケールでのパフォーマンスを維持

チャンク戦略

チャンク処理は検索品質に大きな影響を与えます:

  • チャンクサイズ: Rememberizerはデフォルトのチャンクサイズを1024バイト、200バイトのオーバーラップで使用します

  • 小さいチャンク (512-1024バイト): より正確な一致、特定の質問に適しています

  • 大きいチャンク (1500-2048バイト): 各一致により多くのコンテキスト、広範なトピックに適しています

  • オーバーラップ: チャンクの境界でコンテキストが失われないようにします

クエリ最適化

  • コンテキストウィンドウ: prev_chunks と next_chunks を使用して周囲のコンテンツを取得

  • 結果数: 3-5 件の結果(n パラメータ)から始め、精度のニーズに応じて調整

  • 閾値: 類似スコアで結果をフィルタリングするために t パラメータを調整

高度な使用法

再インデックス作成

Rememberizerは、ベクトル数が事前に定義された閾値を超えると自動的に再インデックス作成をトリガーしますが、以下の後に手動で再インデックス作成を検討してください:

  • 大量のドキュメントをアップロードした場合

  • 埋め込みモデルを変更した場合

  • インデックス作成アルゴリズムを変更した場合

クエリの強化

より良い検索結果のために:

  1. 具体的に 検索クエリを設定する

  2. 文脈を含める 可能な場合は

  3. 自然言語を使用する キーワードではなく

  4. 結果の質に基づいて パラメータを調整する

他のベクターデータベースからの移行

現在、他のベクターデータベースソリューションを使用していて、Rememberizer Vector Storeに移行したい場合は、以下のガイドがデータを効率的に移行するのに役立ちます。

移行の概要

ベクトルデータの移行には以下が含まれます:

  1. ソースベクトルデータベースからデータをエクスポートする

  2. データをRememberizerと互換性のある形式に変換する

  3. データをRememberizerベクトルストアにインポートする

  4. 移行が成功したことを確認する

Rememberizerへの移行の利点

  • PostgreSQL基盤: バックアップとリカバリ機能を備えた成熟したデータベース技術に基づいています

  • 統合エコシステム: 他のRememberizerコンポーネントとのシームレスな接続

  • 管理の簡素化: ベクトル操作のための統一インターフェース

  • 高度なセキュリティ: 行レベルのセキュリティと細かいアクセス制御

  • スケーラブルなアーキテクチャ: データが増えるにつれてパフォーマンスを最適化

Pineconeからの移行

import os
import pinecone
import requests
import json
import time

# Pineconeクライアントのセットアップ
pinecone.init(api_key="PINECONE_API_KEY", environment="PINECONE_ENV")
source_index = pinecone.Index("your-pinecone-index")

# Rememberizerベクターストアクライアントの設定
REMEMBERIZER_API_KEY = "your_rememberizer_api_key"
VECTOR_STORE_ID = "vs_abc123"  # あなたのRememberizerベクターストアID
BASE_URL = "https://api.rememberizer.ai/api/v1"

# 1. マイグレーションのバッチサイズを設定する(データサイズに基づいて調整)
BATCH_SIZE = 100

# 2. Pineconeからベクトルを取得する関数
def fetch_vectors_from_pinecone(index_name, batch_size, cursor=None):
    # 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:
        # リスト操作のない古いPineconeバージョン用
        # これは簡略化されたアプローチであり、実際の実装はデータアクセスパターンに依存します
        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. 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():
        # Pineconeのベクトルデータを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"{vector_id}をスキップします - メタデータにテキストコンテンツが見つかりません")
            continue
            
        data = {
            "name": document_name,
            "content": content,
            # オプション: 追加のメタデータを含める
            "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_name}' が正常にアップロードされました!")
        else:
            print(f"ドキュメント {document_name} のアップロード中にエラーが発生しました: {response.text}")
        
        # レート制限を防ぐために少し遅延を追加
        time.sleep(0.1)

# 4. メイン移行関数
def migrate_pinecone_to_rememberizer():
    cursor = None
    total_migrated = 0
    
    print("Pinecone から Rememberizer への移行を開始しています...")
    
    while True:
        vectors, cursor = fetch_vectors_from_pinecone("your-pinecone-index", BATCH_SIZE, cursor)
        
        if not vectors:
            break
            
        print(f"Pinecone から {len(vectors)} 個のベクトルを取得しました")
        upload_to_rememberizer(vectors)
        
        total_migrated += len(vectors)
        print(f"進捗: {total_migrated} 個のベクトルが移行されました")
        
        if not cursor:
            break
    
    print(f"移行が完了しました! {total_migrated} 個のベクトルが Rememberizer に移行されました")

# マイグレーションを実行する
# migrate_pinecone_to_rememberizer()
const { PineconeClient } = require('@pinecone-database/pinecone');
const axios = require('axios');

// Pineconeの設定
const pineconeApiKey = 'PINECONE_API_KEY';
const pineconeEnvironment = 'PINECONE_ENVIRONMENT';
const pineconeIndexName = 'YOUR_PINECONE_INDEX';

// Rememberizerの設定
const rememberizerApiKey = 'YOUR_REMEMBERIZER_API_KEY';
const vectorStoreId = 'vs_abc123';
const baseUrl = 'https://api.rememberizer.ai/api/v1';

// バッチサイズの設定
const BATCH_SIZE = 100;

// Pineconeクライアントの初期化
async function initPinecone() {
  const pinecone = new PineconeClient();
  await pinecone.init({
    apiKey: pineconeApiKey,
    environment: pineconeEnvironment,
  });
  return pinecone;
}

// Pineconeからベクトルを取得
async function fetchVectorsFromPinecone(pinecone, batchSize, paginationToken = null) {
  const index = pinecone.Index(pineconeIndexName);
  
  try {
    // 新しいPineconeバージョン用
    const listResponse = await index.list({
      limit: batchSize,
      paginationToken: paginationToken
    });
    
    return {
      vectors: listResponse.vectors || {},
      nextToken: listResponse.paginationToken
    };
  } catch (error) {
    // 古いPineconeバージョン用のフォールバック
    // これは簡略化されています; 実際の実装はデータアクセスパターンに依存します
    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 };
  }
}

// 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(`スキップ中 ${vectorId} - メタデータにテキストコンテンツが見つかりません`);
      continue;
    }
    
    const data = {
      name: documentName,
      content: content,
      // オプション: 追加のメタデータを含める
      metadata: vectorData.metadata || {}
    };
    
    try {
      const response = await axios.post(
        `${baseUrl}/vector-stores/${vectorStoreId}/documents/text`,
        data,
        { headers }
      );
      
      if (response.status === 201) {
        console.log(`ドキュメント '${documentName}' が正常にアップロードされました!`);
        results.push({ id: vectorId, success: true });
      } else {
        console.error(`ドキュメント ${documentName} のアップロード中にエラーが発生しました: ${response.statusText}`);
        results.push({ id: vectorId, success: false, error: response.statusText });
      }
    } catch (error) {
      console.error(`ドキュメント ${documentName} のアップロード中にエラーが発生しました: ${error.message}`);
      results.push({ id: vectorId, success: false, error: error.message });
    }
    
    // レート制限を防ぐために小さな遅延を追加
    await new Promise(resolve => setTimeout(resolve, 100));
  }
  
  return results;
}

// メインの移行関数
async function migratePineconeToRememberizer() {
  try {
    console.log('Pineconeから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(`Pineconeから ${Object.keys(vectors).length} ベクトルを取得しました`);
      
      const results = await uploadToRememberizer(vectors);
      const successCount = results.filter(r => r.success).length;
      
      totalMigrated += successCount;
      console.log(`進捗: ${totalMigrated} ベクトルが正常に移行されました`);
      
    } while (nextToken);
    
    console.log(`移行完了! ${totalMigrated} のベクトルがRememberizerに移行されました`);
    
  } catch (error) {
    console.error('移行に失敗しました:', error);
  }
}

// 移行を実行
// migratePineconeToRememberizer();

Qdrantからの移行

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

# Qdrantクライアントのセットアップ
QDRANT_URL = "http://localhost:6333"  # またはあなたのQdrantクラウドURL
QDRANT_API_KEY = "your_qdrant_api_key"  # Qdrant Cloudを使用する場合
QDRANT_COLLECTION_NAME = "your_collection"

qdrant_client = QdrantClient(
    url=QDRANT_URL,
    api_key=QDRANT_API_KEY  # Qdrant Cloud専用
)

# Rememberizerベクターストアクライアントの設定
REMEMBERIZER_API_KEY = "your_rememberizer_api_key"
VECTOR_STORE_ID = "vs_abc123"  # あなたのRememberizerベクターストアID
BASE_URL = "https://api.rememberizer.ai/api/v1"

# 処理のバッチサイズ
BATCH_SIZE = 100

# Qdrantからポイントを取得する関数
def fetch_points_from_qdrant(collection_name, batch_size, offset=0):
    try:
        # ベクトルの次元を決定するためにコレクション情報を取得
        collection_info = qdrant_client.get_collection(collection_name=collection_name)
        
        # ポイントをスクロール
        scroll_result = qdrant_client.scroll(
            collection_name=collection_name,
            limit=batch_size,
            offset=offset,
            with_payload=True,
            with_vectors=True
        )
        
        points = scroll_result[0]  # (points, next_offset) のタプル
        next_offset = scroll_result[1]
        
        return points, next_offset
    except Exception as e:
        print(f"Qdrantからポイントを取得中にエラーが発生しました: {e}")
        return [], None

# Rememberizerにベクトルをアップロードするための関数
def upload_to_rememberizer(points):
    headers = {
        "x-api-key": REMEMBERIZER_API_KEY,
        "Content-Type": "application/json"
    }
    
    results = []
    
    for point in points:
        # 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"スキップ中 {point_id} - ペイロードにテキストコンテンツが見つかりません")
            continue
            
        data = {
            "name": document_name,
            "content": text_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_name}' が正常にアップロードされました!")
                results.append({"id": point_id, "success": True})
            else:
                print(f"ドキュメント {document_name} のアップロード中にエラーが発生しました: {response.text}")
                results.append({"id": point_id, "success": False, "error": response.text})
        except Exception as e:
            print(f"ドキュメント {document_name} のアップロード中に例外が発生しました: {str(e)}")
            results.append({"id": point_id, "success": False, "error": str(e)})
        
        # レート制限を防ぐために少し遅延を追加
        time.sleep(0.1)
    
    return results

# メイン移行関数
def migrate_qdrant_to_rememberizer():
    offset = None
    total_migrated = 0
    
    print("QdrantからRememberizerへの移行を開始します...")
    
    while True:
        points, next_offset = fetch_points_from_qdrant(
            QDRANT_COLLECTION_NAME, 
            BATCH_SIZE,
            offset
        )
        
        if not points:
            break
            
        print(f"Qdrantから{len(points)}ポイントを取得しました")
        
        results = upload_to_rememberizer(points)
        success_count = sum(1 for r in results if r.get("success", False))
        
        total_migrated += success_count
        print(f"進捗: {total_migrated}ポイントが正常に移行されました")
        
        if next_offset is None:
            break
            
        offset = next_offset
    
    print(f"移行完了! {total_migrated}ポイントがRememberizerに移行されました")

# マイグレーションを実行する
# migrate_qdrant_to_rememberizer()
const { QdrantClient } = require('@qdrant/js-client-rest');
const axios = require('axios');

// Qdrantの設定
const qdrantUrl = 'http://localhost:6333'; // またはあなたのQdrantクラウドURL
const qdrantApiKey = 'your_qdrant_api_key'; // Qdrant Cloudを使用する場合
const qdrantCollectionName = 'your_collection';

// Rememberizerの設定
const rememberizerApiKey = 'YOUR_REMEMBERIZER_API_KEY';
const vectorStoreId = 'vs_abc123';
const baseUrl = 'https://api.rememberizer.ai/api/v1';

// バッチサイズの設定
const BATCH_SIZE = 100;

// Qdrantクライアントの初期化
const qdrantClient = new QdrantClient({ 
  url: qdrantUrl,
  apiKey: qdrantApiKey // Qdrant Cloud専用
});

// Qdrantからポイントを取得する
async function fetchPointsFromQdrant(collectionName, batchSize, offset = 0) {
  try {
    // コレクション情報を取得
    const collectionInfo = await qdrantClient.getCollection(collectionName);
    
    // ポイントをスクロール
    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(`Qdrantからポイントを取得中にエラーが発生しました: ${error.message}`);
    return { points: [], nextOffset: null };
  }
}

// Rememberizerにベクトルをアップロードする
async function uploadToRememberizer(points) {
  const headers = {
    'x-api-key': rememberizerApiKey,
    'Content-Type': 'application/json'
  };
  
  const results = [];
  
  for (const point of points) {
    // Qdrantポイントからデータを抽出
    const pointId = point.id;
    const metadata = point.payload || {};
    const textContent = metadata.text || '';
    const documentName = metadata.filename || `qdrant_doc_${pointId}`;
    
    if (!textContent) {
      console.log(`スキップ中: ${pointId} - ペイロードにテキストコンテンツが見つかりません`);
      continue;
    }
    
    const data = {
      name: documentName,
      content: textContent,
      // オプション: 追加のメタデータを含める
      metadata: metadata
    };
    
    try {
      const response = await axios.post(
        `${baseUrl}/vector-stores/${vectorStoreId}/documents/text`,
        data,
        { headers }
      );
      
      if (response.status === 201) {
        console.log(`ドキュメント '${documentName}' が正常にアップロードされました!`);
        results.push({ id: pointId, success: true });
      } else {
        console.error(`ドキュメント ${documentName} のアップロード中にエラーが発生しました: ${response.statusText}`);
        results.push({ id: pointId, success: false, error: response.statusText });
      }
    } catch (error) {
      console.error(`ドキュメント ${documentName} のアップロード中にエラーが発生しました: ${error.message}`);
      results.push({ id: pointId, success: false, error: error.message });
    }
    
    // レート制限を防ぐために小さな遅延を追加
    await new Promise(resolve => setTimeout(resolve, 100));
  }
  
  return results;
}

// メインの移行関数
async function migrateQdrantToRememberizer() {
  try {
    console.log('Qdrantから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(`Qdrantから ${points.length} ポイントを取得しました`);
      
      const results = await uploadToRememberizer(points);
      const successCount = results.filter(r => r.success).length;
      
      totalMigrated += successCount;
      console.log(`進捗: ${totalMigrated} ポイントが正常に移行されました`);
      
    } while (offset !== null);
    
    console.log(`移行完了! ${totalMigrated} ポイントがRememberizerに移行されました`);
    
  } catch (error) {
    console.error('移行に失敗しました:', error);
  }
}

// 移行を実行
// migrateQdrantToRememberizer();

Supabase pgvectorからの移行

すでにSupabaseをpgvectorで使用している場合、Rememberizerへの移行は特に簡単です。なぜなら、両者はpgvector拡張機能を持つPostgreSQLを使用しているからです。

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

環境変数を読み込む

load_dotenv()

Supabase PostgreSQL 設定

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の設定

REMEMBERIZER_API_KEY = os.getenv("REMEMBERIZER_API_KEY") VECTOR_STORE_ID = os.getenv("VECTOR_STORE_ID") # 例: "vs_abc123" BASE_URL = "https://api.rememberizer.ai/api/v1"

処理のバッチサイズ

BATCH_SIZE = 100

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"Supabase PostgreSQLへの接続中にエラーが発生しました: {e}") return None

Supabase pgvectorからドキュメントを取得する

def fetch_documents_from_supabase(conn, batch_size, offset=0): try: cursor = conn.cursor()

    # テーブル構造に基づいてこのクエリを調整してください
    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"Supabaseからドキュメントを取得中にエラーが発生しました: {e}")
    return []

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
    
    # メタデータが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"{doc_id}をスキップします - コンテンツが見つかりません")
        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_name}' が正常にアップロードされました!")
            results.append({"id": doc_id, "success": True})
        else:
            print(f"ドキュメント {document_name} のアップロード中にエラーが発生しました: {response.text}")
            results.append({"id": doc_id, "success": False, "error": response.text})
    except Exception as e:
        print(f"ドキュメント {document_name} のアップロード中に例外が発生しました: {str(e)}")
        results.append({"id": doc_id, "success": False, "error": str(e)})
    
    # レート制限を防ぐために少し遅延を追加
    time.sleep(0.1)

return results

メイン移行関数

def migrate_supabase_to_rememberizer(): conn = connect_to_supabase() if not conn: print("Supabaseへの接続に失敗しました。移行を中止します。") return

offset = 0
total_migrated = 0

print("Supabase pgvectorからRememberizerへの移行を開始します...")

try:
    while True:
        documents = fetch_documents_from_supabase(conn, BATCH_SIZE, offset)
        
        if not documents:
            break
            
        print(f"Supabaseから{len(documents)}件のドキュメントを取得しました")
        
        results = upload_to_rememberizer(documents)
        success_count = sum(1 for r in results if r.get("success", False))
        
        total_migrated += success_count
        print(f"進捗: {total_migrated}件のドキュメントが正常に移行されました")
        
        offset += BATCH_SIZE
        
finally:
    conn.close()

print(f"移行完了!{total_migrated}件のドキュメントがRememberizerに移行されました")

マイグレーションを実行する

migrate_supabase_to_rememberizer()


</div>

<div data-gb-custom-block data-tag="tab" data-title='Node.js'>

```javascript
const { Pool } = require('pg');
const axios = require('axios');
require('dotenv').config();

// Supabase PostgreSQL 設定
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 設定
const rememberizerApiKey = process.env.REMEMBERIZER_API_KEY;
const vectorStoreId = process.env.VECTOR_STORE_ID; // 例: "vs_abc123"
const baseUrl = 'https://api.rememberizer.ai/api/v1';

// バッチサイズ設定
const BATCH_SIZE = 100;

// Supabase pgvector からドキュメントを取得
async function fetchDocumentsFromSupabase(batchSize, offset = 0) {
  try {
    // テーブル構造に基づいてこのクエリを調整
    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(`Supabase からドキュメントを取得中にエラーが発生しました: ${error.message}`);
    return [];
  }
}

// Rememberizer にドキュメントをアップロード
async function uploadToRememberizer(documents) {
  const headers = {
    'x-api-key': rememberizerApiKey,
    'Content-Type': 'application/json'
  };
  
  const results = [];
  
  for (const doc of documents) {
    // メタデータが 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(`スキップ中: ${doc.id} - コンテンツが見つかりません`);
      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(`ドキュメント '${documentName}' が正常にアップロードされました!`);
        results.push({ id: doc.id, success: true });
      } else {
        console.error(`ドキュメント ${documentName} のアップロード中にエラーが発生しました: ${response.statusText}`);
        results.push({ id: doc.id, success: false, error: response.statusText });
      }
    } catch (error) {
      console.error(`ドキュメント ${documentName} のアップロード中にエラーが発生しました: ${error.message}`);
      results.push({ id: doc.id, success: false, error: error.message });
    }
    
    // レート制限を防ぐために少し遅延を追加
    await new Promise(resolve => setTimeout(resolve, 100));
  }
  
  return results;
}

// メイン移行関数
async function migrateSupabaseToRememberizer() {
  try {
    console.log('Supabase pgvector から Rememberizer への移行を開始します...');
    
    let offset = 0;
    let totalMigrated = 0;
    
    while (true) {
      const documents = await fetchDocumentsFromSupabase(BATCH_SIZE, offset);
      
      if (documents.length === 0) {
        break;
      }
      
      console.log(`Supabase から ${documents.length} ドキュメントを取得しました`);
      
      const results = await uploadToRememberizer(documents);
      const successCount = results.filter(r => r.success).length;
      
      totalMigrated += successCount;
      console.log(`進捗: ${totalMigrated} ドキュメントが正常に移行されました`);
      
      offset += BATCH_SIZE;
    }
    
    console.log(`移行完了! ${totalMigrated} 件のドキュメントが Rememberizer に移行されました`);
    
  } catch (error) {
    console.error('移行に失敗しました:', error);
  } finally {
    await supabasePool.end();
  }
}

// 移行を実行
// migrateSupabaseToRememberizer();

移行のベストプラクティス

成功する移行のために、以下の推奨事項に従ってください:

  1. 事前計画:

    • 移行に必要なデータ量と時間を見積もる

    • トラフィックが少ない時間帯に移行をスケジュールする

    • 大規模な移行を開始する前にディスクスペースを増やす

  2. 最初にテスト:

    • Rememberizer にテストベクトルストアを作成する

    • 小さなデータセット(100-1000 ベクトル)を移行する

    • 主要なクエリで検索機能を確認する

  3. データ検証:

    • 移行前後のドキュメント数を比較する

    • 同様の結果を確保するためにベンチマーククエリを実行する

    • メタデータが正しく保持されていることを検証する

  4. パフォーマンスの最適化:

    • 効率のためにバッチ操作を使用する

    • ソースデータベースとターゲットデータベースの地理的な共同配置を考慮する

    • API レート制限を監視し、バッチサイズを適宜調整する

  5. 移行後のステップ:

    • Rememberizer でのインデックス作成を確認する

    • 新しいベクトルストアを指すようにアプリケーション設定を更新する

    • 移行が確認されるまでソースデータベースをバックアップとして保持する

詳細な API リファレンスとエンドポイントのドキュメントについては、ベクターストアのドキュメント ページを訪問してください。


API キーを安全に取り扱い、API キー管理のベストプラクティスに従ってください。

ベクトル埋め込みとベクトルデータベースとは?
新しいベクトルストアを作成
ベクトルストアの詳細を表示
新しいAPIキーを作成
新しいベクトルストアを作成
ベクトルストアの詳細を表示
新しいAPIキーを作成