Python で Azure Cosmos DB for NoSQL 内のベクトルのインデックス作成とクエリを実行する

適用対象: NoSQL

Azure Cosmos DB for NoSQL のベクトル検索は現在プレビュー機能です。 使用する前に、プレビューへの登録が必要です。 この記事では、次の手順について説明します。

  1. Azure Cosmos DB for NoSQL のベクトル検索のプレビューへの登録
  2. ベクトル検索用の Azure Cosmos DB コンテナーの設定
  3. ベクトル埋め込みポリシーの作成
  4. コンテナー インデックス作成ポリシーへのベクトル インデックスの追加
  5. ベクトル インデックスとベクトル埋め込みポリシーを持つコンテナーの作成
  6. 格納されたデータでのベクトル検索の実行。
  7. このガイドでは、ベクトル データを作成して、データのインデックスを作成し、コンテナー内のデータに対してクエリを実行するプロセスについて説明します。

前提条件

プレビューへの登録

Azure Cosmos DB for NoSQL のベクトル検索にはプレビュー機能の登録が必要です。 次の手順で登録します。

  1. Azure Cosmos DB for NoSQL リソース ページに移動します。

  2. [設定] メニュー項目の [機能] ウィンドウを選択します。

  3. [Azure Cosmos DB for NoSQL におけるベクトル検索] を選択します。

  4. 機能の説明を読み、プレビューに登録することを確認します。

  5. プレビューに登録するには [有効にする] を選択します。

Note

登録要求は自動承認されますが、反映されるまで数分かかる場合があります。

次の手順は、Cosmos DB NoSQL アカウントをセットアップしてデータベースを作成する方法を知っていることを前提としています。 ベクトル検索機能は、現在、既存のコンテナーではサポートされていないため、新しいコンテナーを作成し、コンテナーの作成時に、コンテナー レベルのベクトル埋め込みポリシーと、ベクトル インデックス作成ポリシーを指定する必要があります。

インターネットベースの書店のデータベースを作成する例で、各書籍のタイトル、著者名、ISBN、書籍の説明を保存する場合について考えてみましょう。 また、ベクトルの埋め込みを含めるための 2 つのプロパティを定義します。 1 つ目は、"contentVector" プロパティで、書籍のテキストの内容から生成されたテキスト埋め込みを含みます (たとえば、埋め込みを作成する前に "title"、"author"、"isbn"、"description" プロパティを連結します)。 2 つ目は "coverImageVector" で、書籍の表紙の画像から生成されます。

  1. ベクトル検索を実行するフィールドのベクトル埋め込みを作成し、保存します。
  2. ベクトル埋め込みポリシーでベクトル埋め込みパスを指定します。
  3. 必要なベクトル インデックスをコンテナーのインデックス作成ポリシーに含めます。

この記事の以降のセクションでは、コンテナーに格納されている項目の以下の構造について検討します。

{
"title": "book-title", 
"author": "book-author", 
"isbn": "book-isbn", 
"description": "book-description", 
"contentVector": [2, -1, 4, 3, 5, -2, 5, -7, 3, 1], 
"coverImageVector": [0.33, -0.52, 0.45, -0.67, 0.89, -0.34, 0.86, -0.78] 
} 

コンテナーのベクトル埋め込みポリシーを作成します。

次に、コンテナー ベクトル ポリシーを定義する必要があります。 このポリシーは、VectorDistance システム関数でベクトル プロパティの処理方法を Azure Cosmos DB クエリ エンジンに伝えるために使われる情報を提供します。 また、ユーザーが必要な情報を選んで指定する必要がある場合に、それをベクトル インデックス作成ポリシーに通知します。 含まれるベクトル ポリシーには、次の情報が含まれます。

  • "path": ベクトルを含むプロパティ パス
  • "datatype": ベクトルの要素の型 (既定値 Float32)
  • "dimensions": パス内の各ベクトルの長さ (既定値 1536)
  • "distanceFunction": 距離/類似度の計算に使用するメトリック (既定値 Cosine)

書籍の詳細の例では、ベクトル ポリシーは次の JSON の例のようになる場合があります。

vector_embedding_policy = { 
    "vectorEmbeddings": [ 
        { 
            "path": "/coverImageVector", 
            "dataType": "float32", 
            "distanceFunction": "dotproduct", 
            "dimensions": 8 
        }, 
        { 
            "path": "/contentVector", 
            "dataType": "float32", 
            "distanceFunction": "cosine", 
            "dimensions": 10 
        } 
    ]    
} 

インデックス作成ポリシーでのベクトル インデックスの作成

ベクトル埋め込みパスを決定したら、インデックス作成ポリシーにベクトル インデックスを追加する必要があります。 この例では、インデックス作成ポリシーは次のようになります。

indexing_policy = { 
    "includedPaths": [ 
        { 
            "path": "/*" 
        } 
    ], 
    "excludedPaths": [ 
        { 
            "path": "/\"_etag\"/?",
            "path": "/coverImageVector/*",
            "path": "/contentVector/*"
            
        } 
    ], 
    "vectorIndexes": [ 
        {"path": "/coverImageVector", 
         "type": "quantizedFlat" 
        }, 
        {"path": "/contentVector", 
         "type": "quantizedFlat" 
        } 
    ] 
} 

重要

挿入の最適なパフォーマンスを確保するためにインデックス作成ポリシーの "excludedPaths" セクションに追加されたベクトル パス。 ベクトル パスを "excludedPaths" に追加しないと、ベクトル挿入に対してより高い RU 料金と待機時間が発生します。

重要

現在、Azure Cosmos DB for NoSQL のベクトル検索は、新しいコンテナーでのみサポートされています。 コンテナー ベクトル ポリシーとベクトル インデックス作成ポリシーは、後では変更できないので、コンテナーの作成時に両方を設定する必要があります。 どちらのポリシーも、将来のプレビュー機能の改良で変更可能になる予定です。

ベクター ポリシーを使用してコンテナーを作成する

現在、Azure Cosmos DB for NoSQL のベクトル検索機能は新しいコンテナーでのみサポートされているため、コンテナーの作成時にベクトル ポリシーを適用する必要があり、後で変更することはできません。

try:     
    container = db.create_container_if_not_exists( 
                    id=CONTAINER_NAME, 
                    partition_key=PartitionKey(path='/id'), 
                    indexing_policy=indexing_policy, 
                    vector_embedding_policy=vector_embedding_policy) 
    print('Container with id \'{0}\' created'.format(id)) 

except exceptions.CosmosHttpResponseError: 
        raise 

ベクトル類似度検索クエリの実行

目的のベクトル ポリシーでコンテナーを作成し、コンテナーにベクトル データを挿入すると、クエリで Vector Distance システム関数を使用してベクトル検索を行うことができます。 たとえば、料理のレシピに関する書籍を説明から検索する場合、まずクエリ テキストの埋め込みを取得する必要があります。 この例では、クエリ テキスト "food recipe "の埋め込みの生成が必要であるとします。 検索クエリの埋め込みができたら、それをベクトル検索クエリの VectorDistance 関数で使用し、次に示すようにクエリに類似するすべての項目を取得できます。

SELECT TOP 10 c.title, VectorDistance(c.contentVector, [1,2,3,4,5,6,7,8,9,10]) AS SimilarityScore   
FROM c  
ORDER BY VectorDistance(c.contentVector, [1,2,3,4,5,6,7,8,9,10])   

このクエリは、クエリに対する類似度スコアとともに書籍のタイトルを取得します。 Python の例を次に示します。

query_embedding = [1,2,3,4,5,6,7,8,9,10] 
# Query for items 
for item in container.query_items( 
            query='SELECT c.title, VectorDistance(c.contentVector,@embedding) AS SimilarityScore FROM c ORDER BY VectorDistance(c.contentVector,@embedding)', 
            parameters=[ 
                {"name": "@embedding", "value": query_embedding} 
            ], 
            enable_cross_partition_query=True): 
    print(json.dumps(item, indent=True))