.NET 中適用於 NoSQL 的 Azure Cosmos DB 中的索引和查詢向量
使用向量索引和搜尋之前,您必須先啟用此功能。 本文涵蓋下列步驟:
- 在適用於 NoSQL 的 Azure Cosmos DB 功能中啟用向量搜尋。
- 設定 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 或更新版本)。
啟用功能
向量搜尋適用於 NoSQL 的 Azure Cosmos DB 需要完成下列步驟來啟用此功能:
- 瀏覽至您的 Azure Cosmos DB for NoSQL 資源頁面。
- 選取 [設定] 功能表項目下的 [功能] 窗格。
- 選取 [適用於 NoSQL 的 Azure Cosmos DB 中的向量搜尋]。
- 閱讀功能的描述,以確認您想要啟用此功能。
- 選取 [啟用] 以在適用於 NoSQL 的 Azure Cosmos DB 中開啟向量搜尋。
提示
或者,使用 Azure CLI 來更新您的帳戶的功能以支援 NoSQL 向量搜尋。
az cosmosdb update \
--resource-group <resource-group-name> \
--name <account-name> \
--capabilities EnableNoSQLVectorSearch
注意
註冊要求將會自動核准;不過,可能需要 15 分鐘才會生效。
了解向量搜尋中涉及的步驟
讓我們以建立網際網路型的書店資料庫為例,您要儲存每本書的標題、作者、ISBN 和描述。 我們也定義了兩個屬性來包含向量內嵌。 第一個是“contentVector”屬性,其中包含產生自書籍文字內容 (例如,在建立內嵌之前串連「標題」、「作者」、「ISBN」和「描述」屬性) 的文字內嵌。 第二個是從書籍封面影像產生的“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]
}
為您的容器建立向量內嵌原則
接下來,您必須定義容器向量原則。 此原則提供的資訊可用來告知 Azure Cosmos DB 查詢引擎如何處理 VectorDistance 系統函數中的向量屬性。 此原則也會告知向量索引編製原則 (若您選擇指定一個) 所需的資訊。 自主向量原則包含下列資訊:
- “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 費用和延遲較高。
執行向量相似度搜尋查詢
一旦您使用所需的向量原則建立容器,並將向量資料插入容器中,您就可以在查詢中使用向量距離系統函數來執行向量搜尋。 假設您想要藉由查看描述來搜尋食譜相關書籍,您必須先取得查詢文字的內嵌。 在此情況下,您可能會想要針對查詢文字產生內嵌 - 「食譜」。 一旦您對搜尋查詢具有內嵌,就可以在向量搜尋查詢的 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}");
}
}