AlloyDB 用にカスタマイズされた標準の pgvector
PostgreSQL 拡張機能である vector
拡張機能を使用して、AlloyDB for PostgreSQL でハイブリッド検索(テキスト検索、キーワード マッチング、ベクトル検索、意味的類似性を組み合わせた検索)を実行します。
検索の関連性を高めるには、ベクトル類似性検索とテキスト検索を組み合わせたハイブリッド検索を実行します。AlloyDB では、テキスト検索用の Generalized Inverted Index(GIN)インデックスと、ベクトル検索用の Scalable Nearest Neighbors(ScaNN)インデックスを作成できます。次に、両方の検索の結果を組み合わせて、複数の検索結果リストを 1 つのランキング リストに統合するアルゴリズムである Reciprocal Rank Fusion(RRF)を使用して、それらの結果を再度ランク付けし、キーワードの完全一致と意味的類似性の両方に基づいて関連性の高い結果を取得できます。
テキストとベクトル入力を使用して類似性検索を実行する
AlloyDB for PostgreSQL でハイブリッド検索を実行するには、テーブルにベクトル インデックスとテキスト検索インデックスの両方を作成する必要があります。次に、両方の検索結果を結合して再ランク付けすることで、最も関連性の高い情報を表示します。
GIN インデックスを作成する
汎用転置インデックス(GIN インデックス)は、配列、JSONB、全文検索データなどの複合値内の検索に最適化された特殊なインデックス タイプです。
テキストデータに GIN インデックスを作成して全文検索を実行するには、次のコマンドを実行します。
CREATE INDEX INDEX_NAME ON TABLE USING GIN (to_tsvector('english', COLUMN_NAME));
次のように置き換えます。
INDEX_NAME
: 作成するインデックスの名前(例:my-gin-index
)。TABLE
: インデックスを追加するテーブル。COLUMN_NAME
: 検索するテキストデータを格納する列。
ScaNN インデックスを作成する
保存済みベクトル エンベディングを含む列に ScaNN アルゴリズムを使用した 2 レベルのツリー インデックスを適用するには、次の DDL クエリを実行します。
CREATE INDEX INDEX_NAME ON TABLE
USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION)
WITH (num_leaves=NUM_LEAVES_VALUE);
次のように置き換えます。
INDEX_NAME
: 作成するインデックスの名前(例:my-scann-index
)。インデックス名はデータベース全体で共有されます。各インデックス名はデータベース内の各テーブルで一意となるようにしてください。TABLE
: インデックスを追加するテーブル。EMBEDDING_COLUMN
:vector
データを格納する列。DISTANCE_FUNCTION
: このインデックスで使用する距離関数。次のいずれかを選択します。L2 距離:
l2
ドット積:
dot_product
コサイン距離:
cosine
NUM_LEAVES_VALUE
: このインデックスに適用するパーティションの数。1~1048576 の任意の値に設定します。この値を決定する方法の詳細については、ScaNN
インデックスをチューニングするをご覧ください。
さまざまな ScaNN インデックス構成の詳細については、ScaNN
インデックスを作成するをご覧ください。HNSW インデックスを作成することもできます。
Reciprocal Rank Fusion を使用してハイブリッド検索を実行する
ハイブリッド検索では、ベクトル検索とテキスト検索を個別に実行してから、Reciprocal Rank Fusion(RRF)を使用して結果を結合して再ランク付けします。RRF は、ランクベースのアルゴリズムの一種で、複数の検索結果のランキング リストを 1 つのランキング リストに統合するために、各ドキュメントにスコアを割り当てます。このスコアは、すべての貢献リストにおける RRF の逆数ランクに基づいており、ランクが上位のドキュメントほど貢献度が高くなります。全文検索とハイブリッド検索を組み合わせて結果を再ランキングするには、次の SQL クエリを使用します。
WITH vector_search AS (
SELECT id,
RANK () OVER (ORDER BY embedding <=> google_ml.embedding('MODEL_ID', 'TEXT')) AS rank
FROM TABLE
ORDER BY embedding <=> google_ml.embedding('MODEL_ID', 'TEXT') LIMIT 10
),
text_search AS (
SELECT id,
RANK () OVER (ORDER BY ts_rank(to_tsvector('english', COLUMN_NAME), to_tsquery(KEYWORD)) desc)
FROM TABLE
WHERE to_tsvector('english', COLUMN_NAME) @@ to_tsquery(KEYWORD)
ORDER BY ts_rank(to_tsvector('english', COLUMN_NAME), to_tsquery(KEYWORD)) desc
LIMIT 10
)
SELECT
COALESCE(vector_search.id, text_search.id) AS id,
COALESCE(1.0 / (60 + vector_search.rank), 0.0) + COALESCE(1.0 / (60 + text_search.rank), 0.0) AS rrf_score
FROM vector_search FULL OUTER JOIN text_search ON vector_search.id = text_search.id
ORDER BY rrf_score DESC
LIMIT 5;
次のように置き換えます。
MODEL_ID
: クエリするモデルの ID。Vertex AI Model Garden を使用している場合は、モデル ID として
text-embedding-005
を指定します。これらは、AlloyDB がテキスト エンベディングに使用できるクラウドベースのモデルです。詳細については、テキスト エンベディングをご覧ください。TABLE
: データを含むテーブル。TEXT
: ベクトル エンベディングに変換するテキスト。KEYWORD
: 検索するキーワード。COLUMN_NAME
: 検索するテキストデータを格納する列。
ハイブリッド検索クエリと関連する共通テーブル式(CTE)の説明:
vector_search
CTE: 標準のベクトル類似性検索を実行し、コサイン距離順に結果を並べ替えてランクを割り当てます。意味的に最も類似した上位 10 件の商品を取得します。text_search
CTE:to_tsvector
とto_tsquery
を使用してテキスト検索を実行し、ts_rank
で関連性を計算して、最も関連性の高い上位 10 件のテキスト一致を取得します。Final SELECT Statement
CTE:FULL OUTER JOIN
を使用してベクトル検索とテキスト検索の結果を結合し、商品 ID を選択して、RRF スコアを計算し、スコア順に並べ替えて、上位 5 件の結果を取得します。
LangChain を使用してハイブリッド検索を実行する
AlloyDB ベクトルストアを使用したハイブリッド検索では、高密度エンベディング ベクトル検索とキーワードベースの検索という 2 つの異なるルックアップ戦略を組み合わせることで、検索精度を高めます。AlloyDBVectorStore
は、LangChain の VectorStore
クラスの具体的な実装として機能することで LangChain を使用する LangChain ベクトルストア クラスです。AlloyDBVectorStore クラスを使用して AlloyDB でベクトル エンベディングを保存する方法を確認します。
AlloyDBVectorStore
を設定するときに、HybridSearchConfig
クラスを使用してこのハイブリッド検索を有効にして構成できます。
AlloyDB ベクトルストアを使用したハイブリッド検索では、セマンティック検索を同時に実行してクエリの意味とコンテキストを把握し、キーワード検索を実行して正確な語彙の一致を見つけます。両方の検索結果が統合され、より包括的な結果セットが提供されます。