このドキュメントでは、保存されたエンベディングを使用してインデックスを生成し、エンベディングをクエリする方法について説明します。エンベディングの保存の詳細については、ベクトル エンベディングを保存するをご覧ください。
AlloyDB では、ScaNN、IVF、IVFFlat、HNSW インデックスを作成できます。
始める前に
インデックスの作成を開始する前に、以下の前提条件を整える必要があります。
- AlloyDB データベースのテーブルにエンベディング ベクトルが追加されている。 
- Google が AlloyDB 用に拡張した - pgvectorに基づく- vector拡張機能のバージョン- 0.5.0以降がインストールされている。- CREATE EXTENSION IF NOT EXISTS vector;
- ScaNNインデックスを作成するには、- vector拡張機能に加えて- alloydb_scann拡張機能をインストールしてください。- CREATE EXTENSION IF NOT EXISTS alloydb_scann;
インデックスの作成
データベース内のテーブルには、次のいずれかのインデックス タイプを作成できます。
ScaNN インデックスを作成する
AlloyDB alloydb_scann。
Google が開発した PostgreSQL 拡張機能。高可用性を実現します。
[ScaNN
algorithm](https://github.com/google-research/google-research/blob/master/scann/docs/algorithms.md).
ScaNN インデックスは、近似最近傍検索用のツリーベースの量子化インデックスです。
最近傍検索。 と比較して、インデックスの構築時間が短く、メモリ使用量も小さくなります。
HNSW と比較してメモリ使用量が少ない。また、ワークロードに応じて  よりも QPS が速くなります。
ワークロードに基づく HNSW との比較。
AlloyDB データベースのテーブル。ScaNN インデックスを生成しようとすると、
空のテーブルやパーティション分割テーブルに インデックスを作成しようとすると、問題が発生することがあります。詳細
生成されたエラーの詳細については、ScaNN インデックス エラーのトラブルシューティングをご覧ください。
2 レベルツリー ScaNN インデックス
保存済みベクトル エンベディングを含む列に ScaNN アルゴリズムを使用した 2 レベルのツリー インデックスを適用するには、
保存されたベクトル エンベディングを含む列に ScaNN アルゴリズムを使用して 2 レベルのツリー インデックスを作成するには、次の DDL クエリを実行します。
CREATE INDEX INDEX_NAME ON TABLE
  USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION)
  WITH (num_leaves=NUM_LEAVES_VALUE);
次のように置き換えます。
- INDEX_NAME: 削除するインデックスの名前。- create - 例: - my-scann-index。インデックス名は共有されます- データベース全体で実行できます。各インデックス名は、 - テーブルにアクセスできます。 
- TABLE: インデックスを追加するテーブル。
- EMBEDDING_COLUMN:- vectorを格納する列- リレーショナルデータに対応しています 
- DISTANCE_FUNCTION: 使用する距離関数- このインデックスを使用します。次のいずれかを選択します。 - L2 距離: - l2
- ドット積: - dot_product
- コサイン距離: - cosine
 
- NUM_LEAVES_VALUE: 適用するパーティションの数- このインデックス。1~1048576 の任意の値に設定します。詳細情報 - この値を決定する方法の詳細については、 - ScaNNインデックスをチューニングするをご覧ください。
3 レベルのツリー ScaNN インデックス
ScaNN アルゴリズムを使用して列に 3 レベルのツリー インデックスを作成するには
保存されたベクトル エンベディングを含む列に ScaNN アルゴリズムを使用して 2 レベルのツリー インデックスを作成するには、次の DDL クエリを実行します。
CREATE INDEX INDEX_NAME ON TABLE
  USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION)
  WITH (num_leaves=NUM_LEAVES_VALUE, max_num_levels = MAX_NUM_LEVELS);
次のように置き換えます。
- MAX_NUM_LEVELS: の最大レベル数- K 平均法クラスタリング ツリー。2 レベルのツリーベースの量子化の場合は - 1(デフォルト)に設定します。- 量子化の場合は - 2に設定します。
インデックスを作成すると、最近傍探索クエリを実行できます。
インデックスを使用する最近傍探索クエリを実行できます。
指定されたテキストでクエリを実行します](#query)。
インデックス パラメータは、QPS とリコールのバランスを適切にとるように設定する必要があります。
再現率。ScaNN インデックスのチューニングの詳細については、[ScaNN インデックスをチューニングする] をご覧ください。
index](/alloydb/omni/kubernetes/15.7.0/docs/ai/tune-indexes).
このインデックスを、real[] データ型を使用するエンベディング列に作成するには、
ではなく vector を使用するエンベディング列に作成するには、列を vector データ型にキャストします。
CREATE INDEX INDEX_NAME ON TABLE
  USING scann (CAST(EMBEDDING_COLUMN AS vector(DIMENSIONS)) DISTANCE_FUNCTION)
  WITH (num_leaves=NUM_LEAVES_VALUE, max_num_levels = MAX_NUM_LEVELS);
DIMENSIONS は、エンベディング列のディメンション幅に置き換えます。
エンベディング列。ディメンションの確認方法については、
[Vectorvector_dims
functions](https://github.com/pgvector/pgvector?tab=readme-ov-file#vector-functions).
インデックス作成の進行状況を確認するには、pg_stat_progress_create_index ビューを使用します。
SELECT * FROM pg_stat_progress_create_index;
phase 列には、インデックス作成の現在のステータスが表示されます。
インデックスが作成されると、building index: tree training フェーズが消えます。
目標の再現率と QPS のバランスを考慮してインデックスをチューニングするには、ScaNN インデックスをチューニングするをご覧ください。
インデックスを作成したテーブルを分析する
ScaNN インデックスの作成後、ANALYZE コマンドを実行してデータに関する統計情報を更新します。
ANALYZE TABLE;
クエリの実行
エンベディングをデータベースに保存してインデックスを作成した後は、
[pgvector クエリを使用してクエリを実行する
機能](https://github.com/pgvector/pgvector#querying)。次のコマンドは実行できません。
alloydb_scann 拡張機能を使用して一括検索クエリを実行することはできません。
エンベディング ベクトルの最も近いセマンティック ネイバーを見つけるには、
次のサンプルクエリを実行します。ここでは、インデックスの作成時に使用した距離関数を設定します。
インデックスの作成中に発生します。
  SELECT * FROM TABLE
    ORDER BY EMBEDDING_COLUMN DISTANCE_FUNCTION_QUERY ['EMBEDDING']
    LIMIT ROW_COUNT
次のように置き換えます。
- TABLE: テキストを比較するエンベディングを含むテーブル。- テキストを送信します。 
- INDEX_NAME: 使用するインデックスの名前。- 例: - my-scann-index。
- EMBEDDING_COLUMN: 保存されたエンベディングを含む列。- エンベディング。 
- DISTANCE_FUNCTION_QUERY: このクエリで使用する距離関数。- クエリ。使用した距離関数に基づいて、次のいずれかを選択します - インデックスの作成中: - L2 距離: - <->
- 内積: - <#>
- コサイン距離: - <=>
 
- EMBEDDING: 保存されているセマンティック ネイバーの中で最も近いものを見つけるエンベディング ベクトル。- セマンティック近傍を検索します。 
- ROW_COUNT: 返される行数。- 最も適合するものが 1 つだけ必要な場合は、 - 1を指定します。
他のクエリの例については、
クエリ。
embedding() 関数を使用してテキストをベクトルに変換することもできます。
テキストをベクトルに変換します。ベクトルを次のいずれかに適用します。
pgvector 最近傍演算子(L2 距離の場合は <->)のいずれかに適用して、
意味的に最も類似したエンベディング。
embedding() は real 配列を返すため、
pgvector でこれらの値を使用するために embedding() を vector に呼び出す
演算子。
  CREATE EXTENSION IF NOT EXISTS google_ml_integration;
  CREATE EXTENSION IF NOT EXISTS vector;
  SELECT * FROM TABLE
    ORDER BY EMBEDDING_COLUMN::vector
    <-> embedding('MODEL_IDVERSION_TAG', 'TEXT')
    LIMIT ROW_COUNT
次のように置き換えます。
- MODEL_ID: クエリするモデルの ID。- Vertex AI Model Garden を使用している場合は、モデル ID として - text-embedding-005を指定します。これらは、AlloyDB がテキスト エンベディングに使用できるクラウドベースのモデルです。詳細については、テキスト エンベディングをご覧ください。
- 省略可: - VERSION_TAG: クエリするモデルのバージョンタグ。タグの前に- @を付けます。- Vertex AI で - text-embedding英語モデルのいずれかを使用している場合は、モデル バージョンに記載されているバージョンタグのいずれかを指定します(例:- text-embedding-005)。- バージョンタグは常に指定することを強くおすすめします。バージョンタグを指定しない場合、AlloyDB は常に最新のモデル バージョンを使用します。これにより、予期しない結果が生じる可能性があります。 
- TEXT: ベクトル エンベディングに変換するテキスト。