このページでは、保存されたエンベディングを使用してインデックスを生成し、AlloyDB for PostgreSQL で HNSW インデックスを使用してエンベディングをクエリする方法について説明します。エンベディングの保存の詳細については、ベクトル エンベディングを保存するをご覧ください。
始める前に
インデックスの作成を開始する前に、以下の前提条件を整える必要があります。
AlloyDB データベースのテーブルにエンベディング ベクトルが追加されている。
Google が AlloyDB 用に拡張した
pgvectorに基づくvector拡張機能のバージョン0.5.0以降がインストールされている。CREATE EXTENSION IF NOT EXISTS vector;
HNSW インデックスを作成する
AlloyDB は、AlloyDB pgvector 拡張機能を使用して、ストック pgvector で使用可能なグラフベースの hnsw インデックスの作成をサポートしています。hnsw インデックスを使用すると、貪欲探索が行われます。この探索では、最適な結果が見つかるまで、グラフを移動しながらクエリベクトルに最も近い近傍を探し続けます。IVF と比較して、クエリのパフォーマンスは向上しますが、ビルド時間は長くなります。
HNSW アルゴリズムの詳細については、Hierarchical Navigable Small World グラフをご覧ください。
hnsw インデックスを作成するには、次のクエリを実行します。
CREATE INDEX INDEX_NAME ON TABLE
USING hnsw (EMBEDDING_COLUMN DISTANCE_FUNCTION)
WITH (m = NUMBER_OF_CONNECTIONS, ef_construction = 'CANDIDATE_LIST_SIZE');
次のように置き換えます。
INDEX_NAME: 作成するインデックスの名前(例:my-hnsw-index)。TABLE: インデックスを追加するテーブル。EMBEDDING_COLUMN:vectorデータを格納する列。DISTANCE_FUNCTION: このインデックスで使用する距離関数。次のいずれかを選択します。L2 距離:
vector_l2_ops内積:
vector_ip_opsコサイン距離:
vector_cosine_ops
NUMBER_OF_CONNECTIONS: グラフ内のノードからの接続の最大数。デフォルト値の16から始めて、データセットのサイズに応じて値を大きくしてテストできます。CANDIDATE_LIST_SIZE: グラフの構築中に維持される候補リストのサイズ。ノードの最近傍の現在の最良の候補が常に更新されます。この値は、m値の 2 倍を超える値に設定します(例:64)。
インデックス作成の進行状況を確認するには、pg_stat_progress_create_index ビューを使用します。
SELECT * FROM pg_stat_progress_create_index;
phase 列には、インデックス作成の現在のステータスが示されます。インデックスが作成されると、building graph フェーズが消えます。
目標の再現率と QPS のバランスを考慮してインデックスをチューニングするには、hnsw インデックスをチューニングするをご覧ください。
クエリを実行する
エンベディングをデータベースに保存してインデックスを作成した後は、pgvector クエリ機能を使用してクエリを開始できます。
エンベディング ベクトルの最も近いセマンティック ネイバーを見つけるには、次のサンプルクエリを実行します。ここでは、インデックスの作成時に使用した距離関数を設定します。
SELECT * FROM TABLE
ORDER BY EMBEDDING_COLUMN DISTANCE_FUNCTION_QUERY ['EMBEDDING']
LIMIT ROW_COUNT
次のように置き換えます。
TABLE: テキストを比較するエンベディングを含むテーブル。INDEX_NAME: 使用するインデックスの名前。例:my-hnsw-indexEMBEDDING_COLUMN: 保存されたエンベディングを含む列。DISTANCE_FUNCTION_QUERY: このクエリで使用する距離関数。インデックスの作成時に使用した距離関数に基づいて、次のいずれかを選択します。L2 距離:
<->内積:
<#>コサイン距離:
<=>
EMBEDDING: 保存されているセマンティック ネイバーの中で最も近いものを見つけるエンベディング ベクトル。ROW_COUNT: 返される行数。最も適合するものが 1 つだけ必要な場合は、
1を指定します。
他のクエリの例については、クエリをご覧ください。
embedding() 関数を使用してテキストをベクトルに変換することもできます。ベクトルを pgvector 最近傍演算子(L2 距離の場合は <->)のいずれかに適用して、意味的に最も類似したエンベディングを含むデータベース行を見つけます。
embedding() は real 配列を返すため、これらの値を pgvector 演算子で使用するには、embedding() 呼び出しを vector に明示的にキャストする必要があります。
次のステップ
- ScaNN インデックスを作成する
- ベクトル類似性検索を実行する
- ベクトルクエリのパフォーマンスを調整する
- ベクトル インデックス指標
- AlloyDB、pgvector、モデル エンドポイント管理を使用してスマート ショッピング アシスタントを構築する方法について学習する。