ベクトル検索インデックスを作成してクエリを実行する方法
この記事では、 Mosaic AI Vector Search を使用してベクトル検索インデックスを作成およびクエリする方法について説明します。
ベクトル検索UI、Python SDK 、またはREST API を使用して、ベクトル検索エンドポイントやベクトル検索インデックスなどの コンポーネントを作成および管理できます。
必要条件
- Unity Catalog対応ワークスペースであること。
- サーバレス コンピュート enabled. 手順については、 サーバレス コンピュートへの接続を参照してください。
- ソース テーブルでは、チェンジデータフィードが有効になっている必要があります。 手順については、「 での チェンジデータフィードの使用Delta LakeDatabricks 」を参照してください。
- ベクトル検索インデックスを作成するには、インデックスが作成されるカタログスキーマに対する CREATE TABLE 権限が必要です。
- 別のユーザーが所有するインデックスをクエリするには、追加の特権が必要です。 ベクトル検索エンドポイントのクエリを参照してください。
ベクトル検索エンドポイントを作成および管理するためのアクセス許可は、アクセス制御リストを使用して構成されます。 ベクトル検索エンドポイント ACLを参照してください。
取り付け
ベクトル検索 SDK を使用するには、ノートブックにインストールする必要があります。 次のコードを使用して、パッケージをインストールします。
%pip install databricks-vectorsearch
dbutils.library.restartPython()
次に、次のコマンドを使用して VectorSearchClient
をインポートします。
from databricks.vector_search.client import VectorSearchClient
認証
データ保護と認証を参照してください。
ベクトル検索エンドポイントを作成する
ベクトル検索エンドポイントは、Databricks UI、Python SDK、または API を使用して作成できます。
UI を使用したベクトル検索エンドポイントの作成
UI を使用してベクトル検索エンドポイントを作成するには、次の手順に従います。
-
左のサイドバーで、[ コンピュート ]をクリックします。
-
「 ベクトル検索 」タブをクリックし、「 作成 」をクリックします。
-
[ エンドポイントの作成] フォーム が開きます。このエンドポイントの名前を入力します。
-
確認 をクリックします。
Python SDK を使用してベクトル検索エンドポイントを作成する
次の例では、 create_endpoint() SDK 関数を使用して ベクトル検索 エンドポイントを作成します。
# The following line automatically generates a PAT Token for authentication
client = VectorSearchClient()
# The following line uses the service principal token for authentication
# client = VectorSearchClient(service_principal_client_id=<CLIENT_ID>,service_principal_client_secret=<CLIENT_SECRET>)
client.create_endpoint(
name="vector_search_endpoint_name",
endpoint_type="STANDARD"
)
REST API を使用してベクトル検索エンドポイントを作成する
REST API リファレンスドキュメントを参照してください: POST /api/2.0/vector-search/endpoints。
(オプション)埋め込みモデルを提供するエンドポイントを作成して構成する
埋め込み Databricks コンピュートを選択した場合は、事前に構成された基盤モデル APIs エンドポイントを使用するか、モデルサービング エンドポイントを作成して、選択した埋め込みモデルを提供できます。 手順については、トークン単位の従量課金 基盤モデル APIs または エンドポイントを提供する基盤モデルの作成を参照してください。ノートブックの例については、 埋め込みモデルを呼び出すためのノートブックの例を参照してください。
エンべディングエンドポイントを構成する場合、Databricks では、デフォルトの選択である Scale to zero を削除することをお勧めします。 エンドポイントの提供にはウォームアップに数分かかる場合があり、スケールダウンされたエンドポイントを持つインデックスに対する最初のクエリがタイムアウトする可能性があります。
エンべディングエンドポイントがデータセットに対して適切に構成されていない場合、ベクトル検索インデックスの初期化がタイムアウトになる可能性があります。 CPU エンドポイントは、小規模なデータセットとテストにのみ使用してください。 大規模なデータセットの場合は、最適なパフォーマンスを得るために GPU エンドポイントを使用します。
ベクトル検索インデックスを作成する
ベクトル検索インデックスは、UI、Python SDK、または REST API を使用して作成できます。 UI は最も簡単なアプローチです。
インデックスには、次の 2 つのタイプがあります。
- Delta Sync Index は、ソース Delta テーブルと自動的に同期し、Delta テーブル内の基になるデータが変更されると、インデックスを自動的かつ増分的に更新します。
- Direct Vector Access Index は、ベクトルとメタデータの直接読み取りと書き込みをサポートします。 ユーザーは、REST API または Python SDK を使用してこのテーブルを更新する必要があります。 このタイプのインデックスは、UI を使用して作成することはできません。 REST API または SDK を使用する必要があります。
UI を使用したインデックスの作成
-
左のサイドバーで[ カタログ ] をクリックして、カタログエクスプローラーUIを開きます。
-
使用する Delta テーブルに移動します。
-
右上の 「作成 」ボタンをクリックし、ドロップダウンメニューから 「ベクトル検索インデックス 」を選択します。
-
ダイアログのセレクタを使用して、インデックスを設定します。
名前 : Unity Catalog のオンライン テーブルに使用する名前。 名前には
<catalog>.<schema>.<name>
、. 英数字とアンダースコアのみ使用できます。主キー : 主キーとして使用する列。
エンドポイント : 使用するベクトル検索エンドポイントを選択します。
同期する列 : ベクトル インデックスと同期する列を選択します。 このフィールドを空白のままにすると、ソース テーブルのすべての列がインデックスと同期されます。 主キー列と埋め込みソース列または埋め込みベクトル列は常に同期されます。
エンべディングソース : Databricks でDeltaテーブル内のテキスト列のエンべディングをコンピュートするか ( コンピュート embeddings )、 Deltaテーブルに事前計算されたエンべディングが含まれるかどうか ( [ 既存のエンべディング列を使用 ] ) を示します。
- [コンピュート 埋め込み] を選択した場合は、埋め込みコンピュートの列と、埋め込みモデルを提供するエンドポイントを選択します。テキスト列のみがサポートされています。
- [ 既存のエンべディング列を使用 ] を選択した場合は、事前計算されたエンべディングとエンべディングディメンションを含む列を選択します。 事前計算されたエンべディング列の形式は
array[float]
である必要があります。
Sync コンピュート embeddings : この設定を切り替えて、生成されたエンベディングを Unity Catalog テーブルに保存します。 詳細については、「 生成された埋め込みテーブルの保存」を参照してください。
同期モード : [連続 ] は、インデックスを数秒の待機時間と同期させます。 ただし、コンピュート クラスターは連続同期ストリーミング パイプラインを実行するためのプロビジョニングであるため、コストが高くなります。 [Continuous ] と [Triggered] の両方で、更新は増分であり、最後の同期以降に変更されたデータのみが処理されます。
トリガー同期 モードでは、Python SDK または REST API を使用して同期を開始します。Delta Sync インデックスの更新を参照してください。
-
インデックスの構成が完了したら、[ 作成 ] をクリックします。
Python SDK を使用してインデックスを作成する
次の例では、Databricks によるエンべディングコンピュートを使用してDelta同期インデックスを作成します。
client = VectorSearchClient()
index = client.create_delta_sync_index(
endpoint_name="vector_search_demo_endpoint",
source_table_name="vector_search_demo.vector_search.en_wiki",
index_name="vector_search_demo.vector_search.en_wiki_index",
pipeline_type="TRIGGERED",
primary_key="id",
embedding_source_column="text",
embedding_model_endpoint_name="e5-small-v2"
)
次の例では、自己管理型の埋め込みを使用して Delta Sync Index を作成します。 この例では、オプションのパラメーター columns_to_sync
を使用して、インデックスで使用する列のサブセットのみを選択する方法も示しています。
client = VectorSearchClient()
index = client.create_delta_sync_index(
endpoint_name="vector_search_demo_endpoint",
source_table_name="vector_search_demo.vector_search.en_wiki",
index_name="vector_search_demo.vector_search.en_wiki_index",
pipeline_type="TRIGGERED",
primary_key="id",
embedding_dimension=1024,
embedding_vector_column="text_vector"
)
デフォルトでは、ソーステーブルのすべてのカラムがインデックスと同期されます。 列のサブセットのみを同期するには、 columns_to_sync
を使用します。 プライマリ・キーと埋め込みカラムは、常にインデックスに含まれます。
プライマリキーと埋め込みカラム のみを 同期するには、次のように columns_to_sync
で指定する必要があります。
index = client.create_delta_sync_index(
...
columns_to_sync=["id", "text_vector"] # to sync only the primary key and the embedding column
)
追加の列を同期するには、次のように指定します。 プライマリ・キーと埋め込みカラムは、常に同期されるため、含める必要はありません。
index = client.create_delta_sync_index(
...
columns_to_sync=["revisionId", "text"] # to sync the `revisionId` and `text` columns in addition to the primary key and embedding column.
)
次の例では、Direct Vector Access Index を作成します。
client = VectorSearchClient()
index = client.create_direct_access_index(
endpoint_name="storage_endpoint",
index_name=f"{catalog_name}.{schema_name}.{index_name}",
primary_key="id",
embedding_dimension=1024,
embedding_vector_column="text_vector",
schema={
"id": "int",
"field2": "string",
"field3": "float",
"text_vector": "array<float>"}
)
REST API を使用したインデックスの作成
REST API リファレンス ドキュメント ( POST /api/2.0/vector-search/indexes) を参照してください。
生成された埋め込みテーブルを保存
Databricks がエンべディングを生成する場合、生成されたエンべディングを Unity Catalog のテーブルに保存できます。 このテーブルは、ベクトル索引と同じスキーマで作成され、ベクトル索引ページからリンクされます。
テーブルの名前は、ベクトル検索インデックスの名前に _writeback_table
を付加したものです。 名前は編集できません。
このテーブルは、Unity Catalog の他のテーブルと同様にアクセスしてクエリを実行できます。 ただし、テーブルは手動で更新することを意図していないため、削除または変更しないでください。 インデックスが削除されると、テーブルは自動的に削除されます。
ベクトル検索インデックスの更新
Delta Sync インデックスの更新
連続 同期モードで作成されたインデックスは、ソース Delta テーブルが変更されると自動的に更新されます。 トリガー同期 モードを使用している場合は、Python SDK または REST API を使用して同期を開始します。
- Python SDK
- REST API
index.sync()
See the REST API reference documentation: POST /api/2.0/vector-search/indexes/{index_name}/sync.
Direct Vector Access インデックスの更新
Python SDK または REST API を使用して、Direct Vector Access Index のデータを挿入、更新、または削除できます。
- Python SDK
- REST API
index.upsert([{"id": 1,
"field2": "value2",
"field3": 3.0,
"text_vector": [1.0, 2.0, 3.0]
},
{"id": 2,
"field2": "value2",
"field3": 3.0,
"text_vector": [1.1, 2.1, 3.0]
}
])
See the REST API reference documentation: POST /api/2.0/vector-search/indexes.
For production applications, Databricks recommends using service principals instead of personal access tokens. Performance can be improved by up to 100 msec per query.
The following code example illustrates how to update an index using a service principal.
export SP_CLIENT_ID=...
export SP_CLIENT_SECRET=...
export INDEX_NAME=...
export WORKSPACE_URL=https://...
export WORKSPACE_ID=...
# Set authorization details to generate OAuth token
export AUTHORIZATION_DETAILS='{"type":"unity_catalog_permission","securable_type":"table","securable_object_name":"'"$INDEX_NAME"'","operation": "WriteVectorIndex"}'
# Generate OAuth token
export TOKEN=$(curl -X POST --url $WORKSPACE_URL/oidc/v1/token -u "$SP_CLIENT_ID:$SP_CLIENT_SECRET" --data 'grant_type=client_credentials' --data 'scope=all-apis' --data-urlencode 'authorization_details=['"$AUTHORIZATION_DETAILS"']' | jq .access_token | tr -d '"')
# Get index URL
export INDEX_URL=$(curl -X GET -H 'Content-Type: application/json' -H "Authorization: Bearer $TOKEN" --url $WORKSPACE_URL/api/2.0/vector-search/indexes/$INDEX_NAME | jq -r '.status.index_url' | tr -d '"')
# Upsert data into Vector Search index.
curl -X POST -H 'Content-Type: application/json' -H "Authorization: Bearer $TOKEN" --url https://$INDEX_URL/upsert-data --data '{"inputs_json": "[...]"}'
# Delete data from Vector Search index
curl -X DELETE -H 'Content-Type: application/json' -H "Authorization: Bearer $TOKEN" --url https://$INDEX_URL/delete-data --data '{"primary_keys": [...]}'
The following code example illustrates how to update an index using a personal access token (PAT).
export TOKEN=...
export INDEX_NAME=...
export WORKSPACE_URL=https://...
# Upsert data into Vector Search index.
curl -X POST -H 'Content-Type: application/json' -H "Authorization: Bearer $TOKEN" --url $WORKSPACE_URL/api/2.0/vector-search/indexes/$INDEX_NAME/upsert-data --data '{"inputs_json": "..."}'
# Delete data from Vector Search index
curl -X DELETE -H 'Content-Type: application/json' -H "Authorization: Bearer $TOKEN" --url $WORKSPACE_URL/api/2.0/vector-search/indexes/$INDEX_NAME/delete-data --data '{"primary_keys": [...]}'
ベクトル検索エンドポイントのクエリ
ベクトル検索エンドポイントのクエリは、Python SDK、REST API、または SQL vector_search()
AI 関数を使用してのみ実行できます。
エンドポイントをクエリするユーザーがベクトル検索インデックスの所有者でない場合、そのユーザーには次の UC 権限が必要です。
- ベクトル検索インデックスを含むカタログ上のUSE CATALOG。
- ベクトル検索インデックスを含むスキーマに対して USE SCHEMA。
- ベクトル検索インデックスの SELECT です。
ハイブリッドキーワード類似性検索を実行するには、パラメーター query_type
を hybrid
に設定します。 デフォルト値は ann
(近似最近隣内挿法) です。
- Python SDK
- REST API
- SQL
# Delta Sync Index with embeddings computed by Databricks
results = index.similarity_search(
query_text="Greek myths",
columns=["id", "text"],
num_results=2
)
# Delta Sync Index using hybrid search, with embeddings computed by Databricks
results3 = index.similarity_search(
query_text="Greek myths",
columns=["id", "text"],
num_results=2,
query_type="hybrid"
)
# Delta Sync Index with pre-calculated embeddings
results2 = index.similarity_search(
query_vector=[0.2, 0.33, 0.19, 0.52],
columns=["id", "text"],
num_results=2
)
See the REST API reference documentation: POST /api/2.0/vector-search/indexes/{index_name}/query.
For production applications, Databricks recommends using service principals instead of personal access tokens. In addition to improved security and access management, using service principals can improve performance by up to 100 msec per query.
The following code example illustrates how to query an index using a service principal.
export SP_CLIENT_ID=...
export SP_CLIENT_SECRET=...
export INDEX_NAME=...
export WORKSPACE_URL=https://...
export WORKSPACE_ID=...
# Set authorization details to generate OAuth token
export AUTHORIZATION_DETAILS='{"type":"unity_catalog_permission","securable_type":"table","securable_object_name":"'"$INDEX_NAME"'","operation": "ReadVectorIndex"}'
# If you are using an route_optimized embedding model endpoint (TODO: link), then you need to have additional authorization details to invoke the serving endpoint
# export EMBEDDING_MODEL_SERVING_ENDPOINT_ID=...
# export AUTHORIZATION_DETAILS="$AUTHORIZATION_DETAILS"',{"type":"workspace_permission","object_type":"serving-endpoints","object_path":"/serving-endpoints/'"$EMBEDDING_MODEL_SERVING_ENDPOINT_ID"'","actions": ["query_inference_endpoint"]}'
# Generate OAuth token
export TOKEN=$(curl -X POST --url $WORKSPACE_URL/oidc/v1/token -u "$SP_CLIENT_ID:$SP_CLIENT_SECRET" --data 'grant_type=client_credentials' --data 'scope=all-apis' --data-urlencode 'authorization_details=['"$AUTHORIZATION_DETAILS"']' | jq .access_token | tr -d '"')
# Get index URL
export INDEX_URL=$(curl -X GET -H 'Content-Type: application/json' -H "Authorization: Bearer $TOKEN" --url $WORKSPACE_URL/api/2.0/vector-search/indexes/$INDEX_NAME | jq -r '.status.index_url' | tr -d '"')
# Query Vector Search index.
curl -X GET -H 'Content-Type: application/json' -H "Authorization: Bearer $TOKEN" --url https://$INDEX_URL/query --data '{"num_results": 3, "query_vector": [...], "columns": [...], "debug_level": 1}'
# Query Vector Search index.
curl -X GET -H 'Content-Type: application/json' -H "Authorization: Bearer $TOKEN" --url https://$INDEX_URL/query --data '{"num_results": 3, "query_text": "...", "columns": [...], "debug_level": 1}'
The following code example illustrates how to query an index using a personal access token (PAT).
export TOKEN=...
export INDEX_NAME=...
export WORKSPACE_URL=https://...
# Query Vector Search index with `query_vector`
curl -X GET -H 'Content-Type: application/json' -H "Authorization: Bearer $TOKEN" --url $WORKSPACE_URL/api/2.0/vector-search/indexes/$INDEX_NAME/query --data '{"num_results": 3, "query_vector": [...], "columns": [...], "debug_level": 1}'
# Query Vector Search index with `query_text`
curl -X GET -H 'Content-Type: application/json' -H "Authorization: Bearer $TOKEN" --url $WORKSPACE_URL/api/2.0/vector-search/indexes/$INDEX_NAME/query --data '{"num_results": 3, "query_text": "...", "columns": [...], "debug_level": 1}'
The vector_search()
AI function is in Public Preview.
To use this AI function, see vector_search
function.
クエリでフィルターを使用する
クエリでは、Delta テーブル内の任意の列に基づいてフィルターを定義できます。 similarity_search
は、指定したフィルターに一致する行のみを返します。 次のフィルターがサポートされています。
フィルター演算子 | 挙動 | 例 |
---|---|---|
| フィルターを無効にします。 キーの末尾は「NOT」である必要があります。 たとえば、値が "red" の "color NOT" は、色が赤でないドキュメントと一致します。 |
|
| フィールド値がフィルター値より小さいかどうかを確認します。 キーの末尾は「<」でなければなりません。 たとえば、値が 200 の "price <" は、価格が 200 未満のドキュメントと一致します。 |
|
| フィールド値がフィルター値以下であるかどうかを確認します。 キーの末尾は「<=」である必要があります。 たとえば、値が 200 の "price <=" は、価格が 200 以下のドキュメントと一致します。 |
|
| フィールド値がフィルター値より大きいかどうかを確認します。 キーの末尾は「>」である必要があります。 たとえば、値が 200 の "price >" は、価格が 200 より大きいドキュメントと一致します。 |
|
| フィールド値がフィルター値以上かどうかを確認します。 キーの末尾は「>=」である必要があります。 たとえば、値が 200 の "price >=" は、価格が 200 以上のドキュメントと一致します。 |
|
| フィールド値がフィルター値のいずれかと一致するかどうかを確認します。 キーには、複数のサブキーを区切る |
|
| 文字列内の空白で区切られたトークンを照合します。以下のコード例を参照してください。 |
|
フィルタ演算子が指定されていません | フィルターは完全一致をチェックします。 複数の値を指定すると、いずれかの値に一致します。 |
|
次のコード例を参照してください。
- Python SDK
- REST API
- LIKE
# Match rows where `title` exactly matches `Athena` or `Ares`
results = index.similarity_search(
query_text="Greek myths",
columns=["id", "text"],
filters={"title": ["Ares", "Athena"]},
num_results=2
)
# Match rows where `title` or `id` exactly matches `Athena` or `Ares`
results = index.similarity_search(
query_text="Greek myths",
columns=["id", "text"],
filters={"title OR id": ["Ares", "Athena"]},
num_results=2
)
# Match only rows where `title` is not `Hercules`
results = index.similarity_search(
query_text="Greek myths",
columns=["id", "text"],
filters={"title NOT": "Hercules"},
num_results=2
)
LIKE
examples
{"column LIKE": "apple"}
: matches the strings "apple" and "apple pear" but does not match "pineapple" or "pear". Note that it does not match "pineapple" even though it contains a substring "apple" --- it looks for an exact match over whitespace separated tokens like in "apple pear".
{"column NOT LIKE": "apple"}
does the opposite. It matches "pineapple" and "pear" but does not match "apple" or "apple pear".
ノートブックの例
このセクションの例では、ベクトル検索Python SDK の使用方法を示します。
LangChain の例
パッケージとの統合と同様に、 を使用するには、LangChain で を使用する方法Mosaic AI Vector Search Mosaic AI Vector SearchLangChainを参照してください。
次のノートブックは、類似性検索結果を LangChain ドキュメントに変換する方法を示しています。
Python SDK ノートブックを使用したベクトル検索
埋め込みモデルを呼び出すためのノートブックの例
次のノートブックは、埋め込み生成用に Mosaic AI Model Serving エンドポイントを構成する方法を示しています。