.NET の Azure Cosmos DB for NoSQL におけるベクトルのインデックス作成とクエリ
ベクトル インデックス作成と検索を使用する前に、まずこの機能を有効にする必要があります。 この記事では、次の手順について説明します。
- Azure Cosmos DB for NoSQL のベクトル検索機能を有効にします。
- ベクトル検索用の Azure Cosmos DB コンテナーの設定
- ベクトル埋め込みポリシーの作成
- コンテナー インデックス作成ポリシーへのベクトル インデックスの追加
- ベクトル インデックスとベクトル埋め込みポリシーを持つコンテナーの作成
- 格納されたデータにベクトル検索を実行します
このガイドでは、ベクトル データを作成して、データのインデックスを作成し、コンテナー内のデータに対してクエリを実行するプロセスについて説明します。
前提条件
- 既存の Azure Cosmos DB for NoSQL アカウント。
- Azure サブスクリプションをお持ちでない場合は、Azure Cosmos DB for NoSQL を無料でお試しください。
- 既存の Azure サブスクリプションをお持ちの場合は、新しい Azure Cosmos DB for NoSQL アカウントを作成してください。
- Azure Cosmos DB .NET SDK の最新バージョン (リリース: 3.45.0 以降、プレビュー: 3.46.0-preview.0 以降)。
機能を有効にする
Azure Cosmos DB for NoSQL のベクトル検索では、次の手順を実行して機能を有効にする必要があります。
- Azure Cosmos DB for NoSQL リソース ページに移動します。
- [設定] メニュー項目の [機能] ウィンドウを選択します。
- [Azure Cosmos DB for NoSQL のベクトル検索] を選択します。
- 機能の説明を読み、有効にすることを確認します。
- [有効にする] を選択して、Azure Cosmos DB for NoSQL でベクトル検索を有効にします。
ヒント
または、Azure CLI を使って、NoSQL ベクトル検索をサポートするようにアカウントの機能を更新します。
az cosmosdb update \
--resource-group <resource-group-name> \
--name <account-name> \
--capabilities EnableNoSQLVectorSearch
Note
登録要求は自動承認されますが、反映されるまで 15 分かかる場合があります。
ベクトル検索に関する手順の理解
次の手順は、Cosmos DB NoSQL アカウントをセットアップしてデータベースを作成する方法を知っていることを前提としています。 ベクトル検索機能は、現在、既存のコンテナーではサポートされていないため、新しいコンテナーを作成し、コンテナーの作成時に、コンテナー レベルのベクトル埋め込みポリシーと、ベクトル インデックス作成ポリシーを指定する必要があります。
インターネットベースの書店のデータベースを作成する例で、各書籍のタイトル、著者名、ISBN、書籍の説明を保存する場合について考えてみましょう。 また、ベクトル埋め込みを含む 2 つの特性を定義します。 1 つ目は、"contentVector" プロパティで、書籍のテキスト コンテンツから生成されたテキスト埋め込みを含みます (たとえば、埋め込みを作成する前に "title"、"author"、"isbn"、"description" プロパティを連結します)。 2 つ目は "coverImageVector" で、書籍の表紙の画像から生成されます。
- ベクトル検索を実行するフィールドのベクトル埋め込みを作成し、保存します。
- ベクトル埋め込みポリシーでベクトル埋め込みパスを指定します。
- 必要なベクトル インデックスをコンテナーのインデックス作成ポリシーに含めます。
この記事の以降のセクションでは、コンテナーに保存されている項目の以下の構造について検討します。
{
"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 の例のようになります。
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" に追加しないと、ベクトル挿入に対してより高い RU 料金と待機時間が発生します。
ベクトル類似度検索クエリの実行
目的のベクトル ポリシーでコンテナーを作成し、コンテナーにベクトル データを挿入すると、クエリで 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])
このクエリは、クエリに対する類似度スコアとともに書籍のタイトルを取得します。 .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}");
}
}