次の方法で共有


.NET の Azure Cosmos DB for NoSQL におけるベクトルのインデックス作成とクエリ

この記事では、ベクター データを作成し、データのインデックスを作成し、コンテナー内のデータに対してクエリを実行する方法について説明します。

ベクター インデックス作成と検索を使用する前に、まず Azure Cosmos DB for NoSQL でベクター検索を有効にする必要があります。 ベクター検索用に Azure Cosmos DB コンテナーを設定したら、ベクター埋め込みポリシーを作成します。 次に、コンテナー インデックス作成ポリシーにベクター インデックスを追加します。 次に、ベクター インデックスとベクター埋め込みポリシーを含むコンテナーを作成します。 最後に、格納されたデータに対してベクター検索を実行します。

前提条件

機能を有効にする

Azure Cosmos DB for NoSQL のベクター検索を有効にするには、次の手順に従います。

  1. Azure Cosmos DB for NoSQL リソース ページに移動します。
  2. 左側のウィンドウの [設定] で、[ 機能] を選択します。
  3. Azure Cosmos DB for NoSQL でベクター検索を選択します。
  4. 機能の説明を読んで、有効にすることを確認します。
  5. [ 有効にする] を 選択して、Azure Cosmos DB for NoSQL でベクター検索を有効にします。

ヒント

または、Azure CLI を使用してアカウントの機能を更新し、Azure Cosmos DB for NoSQL ベクター検索をサポートします。

az cosmosdb update \
     --resource-group <resource-group-name> \
     --name <account-name> \
     --capabilities EnableNoSQLVectorSearch

登録要求は自動的に適用されますが、有効になるまでに 15 分かかる場合があります。

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

インターネットベースの書店のデータベースを作成する方法の例を見てみましょう。 各書籍のタイトル、作成者、ISBN、および説明情報を格納する必要があります。 また、ベクター埋め込みを含めるために、次の 2 つのプロパティを定義する必要があります。

  • contentVector プロパティには、書籍のテキスト コンテンツから生成されたテキスト埋め込み文字列が含まれています。 たとえば、埋め込みを作成する前に、 titleauthorisbn、および description のプロパティを連結します。
  • 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 クエリ エンジンに通知するために使用される情報を提供します。 このポリシーは、ベクター インデックス作成ポリシーを指定する場合に必要な情報も提供します。

コンテナー ベクター ポリシーには、次の情報が含まれています。

パラメーター Description
path ベクトルを含むプロパティ パス。
datatype ベクターの要素の型。 (既定値は Float32 です)。
dimensions パス内の各ベクターの長さ。 (既定値は 1536 です)。
distanceFunction 距離/類似性の計算に使用されるメトリック。 (既定値は Cosine です)。

書籍の詳細を含む例では、ベクター ポリシーは次の例のようになります。

  Database db = await client.CreateDatabaseIfNotExistsAsync("vector-benchmarking");
  List<Embedding> embeddings = new List<Embedding>()
  {
      new Embedding()
      {
          Path = "/coverImageVector",
          DataType = VectorDataType.Float32,
          DistanceFunction = DistanceFunction.Cosine,
          Dimensions = 8,
      },
      new Embedding()
      {
          Path = "/contentVector",
          DataType = VectorDataType.Float32,
          DistanceFunction = DistanceFunction.Cosine,
          Dimensions = 10,
      }
  };

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

ベクター埋め込みパスを決定したら、インデックス作成ポリシーにベクター インデックスを追加する必要があります。 現時点では、Azure Cosmos DB for NoSQL のベクター検索機能は、新しいコンテナーでのみサポートされています。 コンテナーを作成するときに、ベクター ポリシーを適用します。 後でポリシーを変更することはできません。 インデックス作成ポリシーは、次の例のようになります。

    Collection<Embedding> collection = new Collection<Embedding>(embeddings);
    ContainerProperties properties = new ContainerProperties(id: "vector-container", partitionKeyPath: "/id")
    {   
        VectorEmbeddingPolicy = new(collection),
        IndexingPolicy = new IndexingPolicy()
        {
            VectorIndexes = new()
            {
                new VectorIndexPath()
                {
                    Path = "/vector",
                    Type = VectorIndexType.QuantizedFlat,
                }
            }
        },
    };
    properties.IndexingPolicy.IncludedPaths.Add(new IncludedPath { Path = "/*" });    
    properties.IndexingPolicy.ExcludedPaths.Add(new ExcludedPath { Path = "/vector/*" });

重要

挿入のパフォーマンスを最適化するために、インデックス作成ポリシーの excludedPaths セクションにベクター パスが追加されます。 ベクターパスを excludedPaths に追加しないと、ベクター挿入の要求ユニット料金およびレイテンシが増加します。

ベクター類似性検索クエリを実行する

必要なベクター ポリシーを使用してコンテナーを作成し、ベクター データをコンテナーに挿入した後、クエリで VectorDistance システム関数を使用してベクター検索を実行します。

説明を見て、食品のレシピに関する書籍を検索するとします。 まず、クエリ テキストのエンベディングを取得する必要があります。 この場合、クエリ テキスト 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])   

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

  float[] embedding = {1f,2f,3f,4f,5f,6f,7f,8f,9f,10f};
  var queryDef = new QueryDefinition(
      query: $"SELECT c.title, VectorDistance(c.contentVector,@embedding) AS SimilarityScore FROM c ORDER BY VectorDistance(c.contentVector,@embedding)"
      ).WithParameter("@embedding", embedding);
  using FeedIterator<Object> feed = container.GetItemQueryIterator<Object>(
      queryDefinition: queryDef
  );
  while (feed.HasMoreResults) 
  {
      FeedResponse<Object> response = await feed.ReadNextAsync();
      foreach ( Object item in response)
      {
          Console.WriteLine($"Found item:\t{item}");
      }
  }