このドキュメントでは、OceanBaseの全文インデックスとベクトルインデックスを組み合わせたハイブリッド検索について説明します。
ハイブリッド検索(Hybrid Search)は、ベクトルに基づく意味検索と全文インデックスに基づくキーワード検索を組み合わせ、総合的なランキングにより正確で包括的な検索結果を提供します。ベクトル検索は意味的な類似性のマッチングに長けていますが、正確なキーワード、数字、固有名詞などのマッチング能力は弱いです。一方、全文検索はこの欠点を効果的に補うことができます。そのため、ハイブリッド検索はベクトルデータベースの重要な機能の一つとなり、さまざまな製品で広く利用されています。
使用方法
ハイブリッド検索機能は、新規に追加されたシステムパッケージ DBMS_HYBRID_SEARCH によって提供され、その中には2つのサブ関数が含まれています:
メンバー関数名 |
機能の紹介 |
|---|---|
DBMS_HYBRID_SEARCH.SEARCH |
検索結果をJSON形式で返します。結果は関連性に基づいてソートされます。 |
DBMS_HYBRID_SEARCH.GET_SQL |
実際に実行されたSQL文を文字列形式で返します。 |
詳細な構文とパラメータの説明については、DBMS_HYBRID_SEARCHを参照してください。
注意事項
- 現在、ハイブリッド検索インターフェースはヒープテーブルでのみサポートされています。本記事の例はすべてヒープテーブルで実行されています。
- ハイブリッド検索を使用する場合、返される列の範囲を指定するために
_sourceフィールドを指定することを強く推奨します。指定しない場合、デフォルトでテーブルのすべての列が返されます。ベクトル列が含まれる場合、応答時間(RT)が大幅に増加する可能性があります。
適用シナリオと例
サンプルテーブルの作成とデータの挿入
ハイブリッド検索機能を説明するために、このセクションでは以下のサンプルテーブルを作成し、データを挿入します。これらのテーブルは、後のさまざまなシナリオでの検索例に使用されます。
-
productsテーブル:基本的な商品情報テーブルで、通常のスカラー検索を説明するために使用されます。商品ID、名前、説明、ブランド、カテゴリ、タグ、価格、在庫、公開日、販売中かどうか、およびベクトルフィールドvecを含みます。CREATE TABLE products ( `product_id` varchar(50) DEFAULT NULL, `product_name` varchar(255) DEFAULT NULL, `description` text DEFAULT NULL, `brand` varchar(100) DEFAULT NULL, `category` varchar(100) DEFAULT NULL, `tags` varchar(255) DEFAULT NULL, `price` decimal(10,2) DEFAULT NULL, `stock_quantity` int(11) DEFAULT NULL, `release_date` datetime DEFAULT NULL, `is_on_sale` tinyint(1) DEFAULT NULL, `vec` VECTOR(4) DEFAULT NULL ) ORGANIZATION HEAP;データを挿入します。
INSERT INTO products VALUES ('prod-001', 'Gamer-Pro Mechanical Keyboard', 'A responsive mechanical keyboard with customizable RGB lighting for the ultimate gaming experience.', 'GamerZone', 'Gaming', 'best-seller,gaming-gear,rgb', 149.00, 100, '2023-07-20 00:00:00.000000', 1, '[0.5,0.1,0.6,0.9]'), ('prod-002', 'Gamer-Pro Headset', 'High-fidelity gaming headset with a noise-cancelling microphone.', 'GamerZone', 'Gaming', 'best-seller,gaming-gear,audio', 149.00, 100, '2023-07-20 00:00:00.000000', 1, '[0.1,0.9,0.2,0]'), ('prod-003', 'Eco-Friendly Yoga Mat', 'A non-slip yoga mat made from sustainable and eco-friendly materials.', 'NatureFirst', 'Sports', 'eco-friendly,health', 49.99, 200, '2023-04-22 00:00:00.000000', 0, '[0.1,0.9,0.3,0]'); -
products_fulltextテーブル:productsテーブルを基に、product_name、description、tags列に全文インデックスを作成し、全文検索を説明するために使用されます。CREATE TABLE products_fulltext ( product_id VARCHAR(50), product_name VARCHAR(255), description TEXT, brand VARCHAR(100), category VARCHAR(100), tags VARCHAR(255), price DECIMAL(10, 2), stock_quantity INT, release_date DATETIME, is_on_sale TINYINT(1), vec vector(4), -- 全文検索が必要な列に全文インデックスを作成 FULLTEXT INDEX idx_product_name(product_name), FULLTEXT INDEX idx_description(description), FULLTEXT INDEX idx_tags(tags) ) ORGANIZATION HEAP;データを挿入します。
INSERT INTO products_fulltext VALUES ('prod-001', 'Gamer-Pro Mechanical Keyboard', 'A responsive mechanical keyboard with customizable RGB lighting for the ultimate gaming experience.', 'GamerZone', 'Gaming', 'best-seller,gaming-gear,rgb', 149.00, 100, '2023-07-20 00:00:00.000000', 1, '[0.5,0.1,0.6,0.9]'), ('prod-002', 'Gamer-Pro Headset', 'High-fidelity gaming headset with a noise-cancelling microphone.', 'GamerZone', 'Gaming', 'best-seller,gaming-gear,audio', 149.00, 100, '2023-07-20 00:00:00.000000', 1, '[0.1,0.9,0.2,0]'), ('prod-003', 'Eco-Friendly Yoga Mat', 'A non-slip yoga mat made from sustainable and eco-friendly materials.', 'NatureFirst', 'Sports', 'eco-friendly,health', 49.99, 200, '2023-04-22 00:00:00.000000', 0, '[0.1,0.9,0.3,0]'); -
doc_tableテーブル:スカラー列、ベクトル列、全文インデックス列を含むドキュメントテーブルで、スカラーフィルター条件とハイブリッド検索を伴う全文検索を説明するために使用されます。CREATE TABLE doc_table( c1 INT, vector VECTOR(3), query VARCHAR(255), content VARCHAR(255), VECTOR INDEX idx1(vector) WITH (distance=l2, type=hnsw, lib=vsag), FULLTEXT INDEX idx2(query), FULLTEXT INDEX idx3(content) ) ORGANIZATION HEAP;データを挿入します。
INSERT INTO doc_table VALUES (1, '[1,2,3]', "hello world", "oceanbase Elasticsearch database"), (2, '[1,2,1]', "hello world, what is your name", "oceanbase mysql database"), (3, '[1,1,1]', "hello world, how are you", "oceanbase oracle database"), (4, '[1,3,1]', "real world, where are you from", "postgres oracle database"), (5, '[1,3,2]', "real world, how old are you", "redis oracle database"), (6, '[2,1,1]', "hello world, where are you from", "starrocks oceanbase database"); -
products_vectorテーブル:productsテーブルと構造は似ていますが、vec列に明示的にベクトルインデックスを作成し、純粋なベクトル検索を説明するために使用されます。CREATE TABLE products_vector ( `product_id` varchar(50) DEFAULT NULL, `product_name` varchar(255) DEFAULT NULL, `description` text DEFAULT NULL, `brand` varchar(100) DEFAULT NULL, `category` varchar(100) DEFAULT NULL, `tags` varchar(255) DEFAULT NULL, `price` decimal(10,2) DEFAULT NULL, `stock_quantity` int(11) DEFAULT NULL, `release_date` datetime DEFAULT NULL, `is_on_sale` tinyint(1) DEFAULT NULL, `vec` VECTOR(4) DEFAULT NULL, -- ベクトル検索が必要な列にベクトルインデックスを作成 VECTOR INDEX idx1(vec) WITH (distance=l2, type=hnsw, lib=vsag) ) ORGANIZATION HEAP;データを挿入します。
INSERT INTO products_vector VALUES ('prod-001', 'Gamer-Pro Mechanical Keyboard', 'A responsive mechanical keyboard with customizable RGB lighting for the ultimate gaming experience.', 'GamerZone', 'Gaming', 'best-seller,gaming-gear,rgb', 149.00, 100, '2023-07-20 00:00:00.000000', 1, '[0.5,0.1,0.6,0.9]'), ('prod-002', 'Gamer-Pro Headset', 'High-fidelity gaming headset with a noise-cancelling microphone.', 'GamerZone', 'Gaming', 'best-seller,gaming-gear,audio', 149.00, 100, '2023-07-20 00:00:00.000000', 1, '[0.1,0.9,0.2,0]'), ('prod-003', 'Eco-Friendly Yoga Mat', 'A non-slip yoga mat made from sustainable and eco-friendly materials.', 'NatureFirst', 'Sports', 'eco-friendly,health', 49.99, 200, '2023-04-22 00:00:00.000000', 0, '[0.1,0.9,0.3,0]');
通常のスカラー検索
通常のベクトル検索の適用シナリオは以下のとおりです:
- エコマーケットプレイスの商品検索:ユーザーが特定ブランドのすべての商品を表示したい場合。例えば、
GamerZoneブランドのすべての商品を表示したい場合。 - コンテンツ管理システム:管理者が特定のカテゴリの記事やドキュメントをフィルタリングする必要がある場合。例えば、特定の著者のすべての記事を検索する場合。
- ユーザー管理システム:特定のステータスまたはロールを持つユーザーを検索する場合。例えば、すべてのVIPユーザーを検索する場合。
例:
検索パラメータを設定します。
SET @parm = '{ "query": { "bool": { "must": [ {"term": {"brand": "GamerZone"}} ] } }, "_source": ["product_id", "product_name", "description", "brand", "category", "tags", "price", "stock_quantity", "release_date", "is_on_sale"] }';brandが"GamerZone"であるすべてのレコードを検索します。SELECT json_pretty(DBMS_HYBRID_SEARCH.SEARCH('products', @parm));実行結果は次のとおりです:
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | json_pretty(DBMS_HYBRID_SEARCH.SEARCH('products', @parm)) | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | [ { "tags": "best-seller,gaming-gear,rgb", "brand": "GamerZone", "price": 149.00, "_score": 1, "category": "Gaming", "is_on_sale": 1, "product_id": "prod-004", "description": "A responsive mechanical keyboard with customizable RGB lighting for the ultimate gaming experience.", "product_name": "Gamer-Pro Mechanical Keyboard", "release_date": "2023-07-20 00:00:00.000000", "stock_quantity": 100 }, { "tags": "best-seller,gaming-gear,audio", "brand": "GamerZone", "price": 149.00, "_score": 1, "category": "Gaming", "is_on_sale": 1, "product_id": "prod-009", "description": "High-fidelity gaming headset with a noise-cancelling microphone.", "product_name": "Gamer-Pro Headset", "release_date": "2023-07-20 00:00:00.000000", "stock_quantity": 100 } ] | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set
通常のスカラー範囲検索
通常のスカラー検索の適用シナリオは以下のとおりです:
- 価格帯域のフィルタリング:Eコマースプラットフォームが価格帯域で商品をフィルタリングします。例えば、価格が
[30~80]の範囲にある商品を検索します。 - 時間帯域クエリ:特定の時間帯内の注文やログを検索します。例えば、直近30日間の注文を検索します。
- 数値範囲のフィルタリング:評価点数や在庫数などの数値範囲をフィルタリングします。例えば、評価点数が
[4~5]の範囲にある商品を検索します。
例:
検索パラメータを設定します。
SET @parm = '{ "query": { "range" : { "price" : { "gte" : 30, "lte" : 80 } } }, "_source": ["product_id", "product_name", "description", "brand", "category", "tags", "price", "stock_quantity", "release_date", "is_on_sale"] }';priceが[30~80]の範囲にあるすべてのレコードを検索します。SELECT json_pretty(DBMS_HYBRID_SEARCH.SEARCH('products', @parm));実行結果は次のとおりです:
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | json_pretty(DBMS_HYBRID_SEARCH.SEARCH('products', @parm)) | +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | [ { "tags": "eco-friendly,health", "brand": "NatureFirst", "price": 49.99, "_score": true, "category": "Sports", "is_on_sale": 0, "product_id": "prod-003", "description": "A non-slip yoga mat made from sustainable and eco-friendly materials.", "product_name": "Eco-Friendly Yoga Mat", "release_date": "2023-04-22 00:00:00.000000", "stock_quantity": 200 } ] | +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set
フルテキスト検索
フルテキスト検索の主なユースケースは以下のとおりです:
- ドキュメント検索:大量のドキュメントから特定のキーワードを含む内容を検索します。例えば、FAQから
"使い方"を含むドキュメントを検索する場合です。 - 商品検索:商品名や説明に基づいてあいまい検索を行います。例えば、
"OceanBase"を含む商品を検索する場合です。 - ナレッジベース検索:FAQやヘルプドキュメントから関連する質問を検索します。例えば、カスタマーサポートシステムのナレッジベースで関連する質問の答えを検索する場合です。
例:
検索パラメータを設定します。
SET @query_str_with_mini = '{ "query": { "query_string": { "type": "best_fields", "fields": ["product_name^3", "description^2.5", "tags^1.5"], "query": "Gamer-Pro^2 keyboard^1.5 audio^1.2", "boost": 1.5 } }, "_source": ["product_id", "product_name", "description", "brand", "category", "tags", "price", "stock_quantity", "release_date", "is_on_sale"] }';product_name、description、tagsフィールドにキーワード"Gamer-Pro"、"keyboard"、"audio"が含まれるレコードを検索し、設定されたフィールドとキーワードの重みに基づいて並べ替えます。SELECT json_pretty(DBMS_HYBRID_SEARCH.SEARCH('products_fulltext', @query_str_with_mini));実行結果は次のとおりです:
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | json_pretty(DBMS_HYBRID_SEARCH.SEARCH('products_fulltext', @query_str_with_mini)) | +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | [ { "tags": "best-seller,gaming-gear,rgb", "brand": "GamerZone", "price": 149.00, "_score": 4.569735248749978, "category": "Gaming", "is_on_sale": 1, "product_id": "prod-001", "description": "A responsive mechanical keyboard with customizable RGB lighting for the ultimate gaming experience.", "product_name": "Gamer-Pro Mechanical Keyboard", "release_date": "2023-07-20 00:00:00.000000", "stock_quantity": 100 }, { "tags": "best-seller,gaming-gear,audio", "brand": "GamerZone", "price": 149.00, "_score": 1.7338881172399914, "category": "Gaming", "is_on_sale": 1, "product_id": "prod-002", "description": "High-fidelity gaming headset with a noise-cancelling microphone.", "product_name": "Gamer-Pro Headset", "release_date": "2023-07-20 00:00:00.000000", "stock_quantity": 100 } ] | +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set
スカラーフィルター条件を含む全文検索
スカラーフィルター条件を含む全文検索の適用シナリオは以下のとおりです:
- 厳密検索:特定の条件下でテキスト検索を行います。例えば、公開済みの記事の中から特定のキーワードを検索する場合などです。
- 権限制御:ユーザーが権限を持つデータ範囲内で検索を行います。例えば、注文システムが特定の期間の注文の中から商品情報を検索する場合などです。
- 分類検索:特定の分類内でキーワード検索を行います。例えば、ユーザーシステムがアクティブユーザーの中から特定のユーザー情報を検索する場合などです。
例:
検索パラメータを設定します。
-- フィルター条件で、スカラーフィルター条件 c1 >= 2 を指定します SET @query_str = '{ "query": { "bool" : { "must" : [ {"query_string": { "fields": ["query", "content"], "query": "hello what oceanbase mysql"} } ], "filter" : [ {"range": {"c1": {"gte" : 2}}} ] } }, "_source": ["c1", "query", "content"] }';すべての
c1が 2 以上のレコードを検索します。SELECT json_pretty(DBMS_HYBRID_SEARCH.SEARCH('doc_table', @query_str));実行結果は次のとおりです:
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | json_pretty(DBMS_HYBRID_SEARCH.SEARCH('doc_table', @query_str)) | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | [ { "c1": 2, "query": "hello world, what is your name", "_score": 2.170969786679347, "content": "oceanbase mysql database" }, { "c1": 3, "query": "hello world, how are you", "_score": 0.3503184713375797, "content": "oceanbase oracle database" }, { "c1": 6, "query": "hello world, where are you from", "_score": 0.3503184713375797, "content": "starrocks oceanbase database" } ] | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set
ベクトル検索
ベクトル検索の適用シナリオは以下のとおりです:
- セマンティック検索:セマンティック類似性に基づいて関連コンテンツを検索します。例えば、ナレッジベース内で意味的に関連する質問と回答を検索します。
- レコメンデーションシステム:ユーザーの嗜好に基づいて類似商品を推薦します。例えば、Eコマースプラットフォームで類似商品を推薦します。
- 画像検索:画像特徴に基づいて類似画像を検索します。例えば、画像ライブラリ内で類似画像を検索します。
- スマートQ&A:ナレッジベース内で意味的に関連する質問と回答を検索します。例えば、カスタマーサポートシステムのナレッジベース内で意味的に関連する質問と回答を検索します。
例:
検索パラメータを設定します。
-- field はベクトルフィールドを指し、k は返される結果の数(最近の k 個の結果)を指定し、query_vector は検索するベクトルを指定します。 SET @parm = '{ "knn" : { "field": "vec", "k": 3, "query_vector": [0.5,0.1,0.6,0.9] }, "_source": ["product_id", "product_name", "description", "brand", "category", "tags", "price", "stock_quantity", "release_date", "is_on_sale"] }';すべての
vecが[0.5,0.1,0.6,0.9]と類似しているレコードを検索します。SELECT json_pretty(DBMS_HYBRID_SEARCH.SEARCH('products_vector', @parm));実行結果は次のとおりです:
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | json_pretty(DBMS_HYBRID_SEARCH.SEARCH('products_vector', @parm)) | +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | [ { "tags": "best-seller,gaming-gear,rgb", "brand": "GamerZone", "price": 149.00, "_score": 1.0, "category": "Gaming", "is_on_sale": 1, "product_id": "prod-001", "description": "A responsive mechanical keyboard with customizable RGB lighting for the ultimate gaming experience.", "product_name": "Gamer-Pro Mechanical Keyboard", "release_date": "2023-07-20 00:00:00.000000", "stock_quantity": 100 }, { "tags": "eco-friendly,health", "brand": "NatureFirst", "price": 49.99, "_score": 0.43405784, "category": "Sports", "is_on_sale": 0, "product_id": "prod-003", "description": "A non-slip yoga mat made from sustainable and eco-friendly materials.", "product_name": "Eco-Friendly Yoga Mat", "release_date": "2023-04-22 00:00:00.000000", "stock_quantity": 200 }, { "tags": "best-seller,gaming-gear,audio", "brand": "GamerZone", "price": 149.00, "_score": 0.42910841, "category": "Gaming", "is_on_sale": 1, "product_id": "prod-002", "description": "High-fidelity gaming headset with a noise-cancelling microphone.", "product_name": "Gamer-Pro Headset", "release_date": "2023-07-20 00:00:00.000000", "stock_quantity": 100 } ] | +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set
スカラーフィルター条件を持つベクトル検索
スカラーフィルター条件を持つベクトル検索の適用シナリオは以下のとおりです:
- 厳密検索:特定の条件下でテキスト検索を行います。例えば、公開済みの記事の中から特定のキーワードを検索する場合などです。
- 権限制御:ユーザーが権限を持つデータ範囲内で検索を行います。例えば、注文システムが特定の期間の注文の中から商品情報を検索する場合などです。
- 分類検索:特定の分類内でキーワード検索を行います。例えば、ユーザーシステムがアクティブユーザーの中から特定のユーザー情報を検索する場合などです。
例:
検索パラメータを設定します。
-- スカラーフィルター条件 brand = "GamerZone" を指定 SET @parm = '{ "knn" : { "field": "vec", "k": 3, "query_vector": [0.1,0.5,0.3,0.7], "filter" : [ {"term" : {"brand": "GamerZone"} } ] }, "_source": ["product_id", "product_name", "description", "brand", "category", "tags", "price", "stock_quantity", "release_date", "is_on_sale"] }';すべての
vecが[0.1,0.5,0.3,0.7]に類似し、かつbrandが"GamerZone"のレコードを検索します。SELECT json_pretty(DBMS_HYBRID_SEARCH.SEARCH('products_vector', @parm));実行結果は次のとおりです:
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | json_pretty(DBMS_HYBRID_SEARCH.SEARCH('products_vector', @parm)) | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | [ { "tags": "best-seller,gaming-gear,rgb", "brand": "GamerZone", "price": 149.00, "_score": 0.59850837, "category": "Gaming", "is_on_sale": 1, "product_id": "prod-001", "description": "A responsive mechanical keyboard with customizable RGB lighting for the ultimate gaming experience.", "product_name": "Gamer-Pro Mechanical Keyboard", "release_date": "2023-07-20 00:00:00.000000", "stock_quantity": 100 }, { "tags": "best-seller,gaming-gear,audio", "brand": "GamerZone", "price": 149.00, "_score": 0.55175342, "category": "Gaming", "is_on_sale": 1, "product_id": "prod-002", "description": "High-fidelity gaming headset with a noise-cancelling microphone.", "product_name": "Gamer-Pro Headset", "release_date": "2023-07-20 00:00:00.000000", "stock_quantity": 100 } ] | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set
マルチベクトル検索
注意
この機能はV4.4.1 HotFix1バージョンからサポートされています。
マルチベクトル検索とは、複数のベクトルインデックスで検索を行い、最も類似したレコードを返すことです。
例:
検索パラメータを設定します。
-- 3路ベクトル検索を指定し、各路でベクトルインデックスフィールドを指定して検索し、結果数とクエリベクトルを返す SET @param_multi_knn = '{ "knn" : [{ "field": "vec1", "k": 5, "query_vector": [0.5,0.1,0.6,0.9] }, { "field": "vec2", "k": 5, "query_vector": [0.2,0.3,0.4,0.5] }, { "field": "vec3", "k": 5, "query_vector": [0.1,0.2,0.3,0.4] } ], "size" : 5, "_source": ["product_id", "product_name", "description"] }';クエリを実行し、検索結果を返します。
SELECT json_pretty(DBMS_HYBRID_SEARCH.SEARCH('products_multi_vector', @param_multi_knn));+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | json_pretty(DBMS_HYBRID_SEARCH.SEARCH('products_multi_vector', @param_multi_knn)) | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | [ { "_score": 3.0, "product_id": "prod-001", "description": "A responsive mechanical keyboard", "product_name": "Gamer-Pro Mechanical Keyboard" }, { "_score": 2.0957750699999997, "product_id": "prod-002", "description": "High-fidelity gaming headset", "product_name": "Gamer-Pro Headset" }, { "_score": 1.86262927, "product_id": "prod-003", "description": "A non-slip yoga mat", "product_name": "Eco-Friendly Yoga Mat" } ] | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set
フルテキストとベクトルのハイブリッド検索
フルテキストとベクトルのハイブリッド検索の適用シナリオは以下の通りです:
- インテリジェント検索:キーワードとセマンティック理解を組み合わせた総合的な検索。例えば、ユーザーが
"ゲーミングキーボードが必要です"と入力すると、システムは"ゲーム"、"キーボード"のキーワードに一致させるだけでなく、"ゲーム機器"の意味も理解します。 - ドキュメント検索:大量のドキュメントにおいて、厳密なキーワード一致とセマンティック理解の両方をサポートします。例えば、
"データベース最適化"を検索すると、この単語を含むドキュメントに一致させるだけでなく、"パフォーマンスチューニング"、"クエリ最適化"などの意味的に関連する内容も見つけ出します。 - 商品推薦:eコマースプラットフォームは、商品名検索とニーズ説明検索の両方をサポートします。例えば、ユーザーが
"オフィスに適したノートパソコン"と説明すると、キーワードに一致させるだけでなく、"ビジネスオフィス"の意味的ニーズも理解します。
例:
検索パラメータを設定します。
SET @parm = '{ "query": { "bool": { "should": [ {"match": {"query": "hi hello"}}, {"match": { "content": "oceanbase mysql" }} ] } }, "knn" : { "field": "vector", "k": 5, "query_vector": [1,2,3] }, "_source" : ["query", "content", "_keyword_score", "_semantic_score"] }';クエリを実行し、検索結果を返します。
SELECT json_pretty(DBMS_HYBRID_SEARCH.SEARCH('doc_table', @parm));実行結果は次のとおりです:
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | json_pretty(dbms_hybrid_search.search('doc_table', @parm)) | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | [ { "query": "hello world, what is your name", "_score": 2.835628417884166, "content": "oceanbase mysql database", "_keyword_score": 2.5022950878841663, "_semantic_score": 0.33333333 }, { "query": "hello world", "_score": 1.7219400929592013, "content": "oceanbase Elasticsearch database", "_keyword_score": 0.7219400929592014, "_semantic_score": 1.0 }, { "query": "hello world, how are you", "_score": 1.0096539326751595, "content": "oceanbase oracle database", "_keyword_score": 0.7006369426751594, "_semantic_score": 0.30901699 }, { "query": "real world, how old are you", "_score": 0.41421356, "content": "redis oracle database", "_keyword_score": null, "_semantic_score": 0.41421356 }, { "query": "real world, where are you from", "_score": 0.30901699, "content": "postgres oracle database", "_keyword_score": null, "_semantic_score": 0.30901699 } ] |
フルテキストとベクトルのRRFハイブリッド検索
注意
この機能はV4.4.1 HotFix1バージョンからサポートされています。
フルテキストサブクエリとベクトルサブクエリの結果セットは、デフォルトで加重混合されます。Rank構文を使用して、融合方式をRRF(Reciprocal Rank Fusion)ソート混合に設定できます。適用シナリオの例:
- 多次元ソート:複数の検索次元の結果を総合的に考慮する必要があります。例えば、学術検索システムでは、論文データベース内で検索する際、キーワードの一致度と意味的関連性の両方を考慮する必要があります。
- 公平性要件:異なる検索方法の結果が適切に表示されることを保証する。例えば、eコマースプラットフォームでは、商品のタイトルや説明などのテキスト情報だけでなく、商品の画像や動画などの視覚的情報も考慮する必要があります。
- 複雑なクエリ:複数のクエリ条件を含む複雑な検索シナリオ。例えば、医療システムでは、患者の症状の記述だけでなく、病歴や検査結果なども考慮する必要があります。
例:
検索パラメータを設定します。
SET @rrf_query_param = '{
"query": {
"query_string": {
"fields": ["title", "author", "description"],
"query": "fiction American Dream"
}
},
"knn" : {
"field": "vector_embedding",
"k": 5,
"query_vector": [0.1, 0.2, 0.3, 0.4]
},
"rank" : {
"rrf" : {
"rank_window_size" : 10,
"rank_constant" : 60
}
},
"_source": ["title", "author", "description"]
}';
RRFアルゴリズムは、複数のサブクエリ結果セットのランキングを融合し、最終的な関連性スコアを計算します。計算式は以下のとおりです:
score = 0.0
for q in queries:
if d in result(q):
score += 1.0 / ( k + rank( result(q), d ) ) # Kは設定されたrank_constantです
return score
まとめ
本記事で示した例は、ハイブリッド検索機能の強力な応用価値を示しています:
- インテリジェントな検索の向上:従来のキーワード検索に意味理解を融合し、より正確でユーザーの意図に合致する検索結果を提供します。
- ユーザーエクスペリエンスの最適化:自然言語クエリをサポートし、操作を簡素化して情報取得効率を向上させます。
- 様々なビジネスの支援:eコマース、コンテンツ管理、ナレッジベース、インテリジェントカスタマーサポートなどのシナリオで広く利用され、基本的なフィルタリングからインテリジェントな推薦まで、包括的にカバーします。
- 技術の統合による利点:厳密一致と意味理解を組み合わせることで、検索結果の精度と網羅性を大幅に向上させます。
ハイブリッド検索機能は、大量の非構造化データを処理し、インテリジェントな検索および推薦システムを構築する理想的な選択肢です。