Azure Cosmos DB for MongoDB vCore 的向量存放區
適用於: MongoDB 虛擬核心
使用 Azure Cosmos DB for MongoDB vCore 中的整合向量資料庫將 AI 型應用程式與儲存在 Azure Cosmos DB 中的資料無縫連線。 這項整合可以包括您使用 Azure OpenAI 內嵌所建置的應用程式。 本機整合的向量資料庫使您能夠有效率地儲存、索引及查詢直接儲存在 Azure Cosmos DB for MongoDB vCore 中的高維度向量資料以及用於建立向量資料的原始資料。 它消除了將資料傳輸到替代向量儲存的需求並產生額外的成本。
什麼是向量存放區?
向量存放區或向量資料庫是用來儲存及管理向量內嵌的資料庫,這是高維度空間中資料的數學表示法。 在此空間中,每個維度各對應至資料的一個特徵,且有數萬個維度可用來代表複雜的資料。 向量在此空間中的位置代表其特性。 單字、片語或整份文件、影像、音訊和其他類型的資料,全都可以向量化。
向量存放區如何運作?
在向量存放區中,向量搜尋演算法可用來編製索引和查詢內嵌。 一些已知的向量搜尋演算法包括階層式導覽小型世界 (HNSW)、反轉檔案 (IVF)、DiskANN 等。向量搜尋方法可協助您根據資料性質來尋找類似的項目,而不是根據屬性欄位尋找完全相符的項目。 此技術適用於搜尋類似文字、尋找相關影像、提出建議,甚至偵測異常這類應用程式。 其運作方式是利用內嵌 API 的機器學習模型,查詢您所建立的資料向量內嵌 (數字清單)。 內嵌 API 的範例是 Azure OpenAI 內嵌或 Hugging Face on Azure。 向量搜尋會測量資料向量與查詢向量之間的距離。 最接近查詢向量的資料向量就是所找到語意最類似的資料向量。
在 Azure Cosmos DB for MongoDB vCore 的整合向量資料庫中,內嵌可以與原始資料一起儲存、編製索引和查詢。 此方法可讓您在複寫個別純向量資料庫中的資料時,無需支付額外的成本。 此外,此結構會一併保存向量內嵌和原始資料,進一步簡化多模資料作業,並提高資料一致性、規模和效能。
建立向量索引
要對文件中的向量屬性執行向量相似性搜索,您必須先建立向量索引。
使用 HNSW 建立向量索引
您可以在 M40 集群層及更高層上建立 (階層式可導航小世界) 索引。 若要建立 HSNW 索引,您需要依照下列範本建立向量索引,其中 "kind"
參數設定為 "vector-hnsw"
:
{
"createIndexes": "<collection_name>",
"indexes": [
{
"name": "<index_name>",
"key": {
"<path_to_property>": "cosmosSearch"
},
"cosmosSearchOptions": {
"kind": "vector-hnsw",
"m": <integer_value>,
"efConstruction": <integer_value>,
"similarity": "<string_value>",
"dimensions": <integer_value>
}
}
]
}
欄位 | 類型 | 描述 |
---|---|---|
index_name |
string | 索引的唯一名稱。 |
path_to_property |
string | 包含向量的屬性的路徑。 此路徑可以是最上層屬性或屬性的點標記法路徑。 如果使用點標記法路徑,則所有非分葉元素都不能是陣列。 向量必須是要編製索引的 number[] ,並在向量搜尋結果中予以傳回。 |
kind |
string | 要建立的向量索引類型。 選項為 vector-ivf 和 vector-hnsw : 注意 vector-ivf 在所有叢集層上可用,vector-hnsw 在 M40 叢集層及更高層上可用。 |
m |
整數 | 每層的連線數目上限 (預設為 16 、最小值為 2 、最大值為 100 )。 較高的 m 適合具有高維度和/或高精確度需求的資料集。 |
efConstruction |
整數 | 用於建構圖形的動態候選清單大小 (預設為 64 、最小值為 4 、最大值為 1000 )。 較高的 efConstruction 將會導致更好的索引品質和更高的精確度,但也會增加建立索引所需的時間。 efConstruction 必須至少為 2 * m |
similarity |
string | 與索引搭配使用的相似度計量。 可能的選項是 COS (餘弦距離)、L2 (歐幾里得距離) 和 IP (內積)。 |
dimensions |
整數 | 向量相似度的維度數目。 所支援維度數目上限為 2000 。 |
使用 HNSW 來執行向量搜尋
若要執行向量搜尋,請搭配使用查詢的 $search
彙總管線階段與 cosmosSearch
運算子。
{
"$search": {
"cosmosSearch": {
"vector": <query_vector>,
"path": "<path_to_property>",
"k": <num_results_to_return>,
"efSearch": <integer_value>
},
}
}
}
欄位 | 類型 | 描述 |
---|---|---|
efSearch |
整數 | 搜尋的動態候選清單大小 (預設為 40 )。 較高的值會以速度為代價提供更佳的重新叫用。 |
k |
整數 | 要傳回的結果數目。 其應該小於或等於 efSearch |
注意
使用大型資料集建立 HSNW 索引可能會導致 Azure Cosmos DB for MongoDB vCore 資源記憶體不足,或者可能會限制資料庫上執行的其他操作的效能。 如果遇到此類問題,可以透過將資源擴充到更高的叢集層或減少資料集的大小來緩解這些問題。
使用 IVF 建立向量索引
若要使用 IVF (反轉檔案) 演算法建立向量索引,請使用以下 createIndexes
範本並將 "kind"
參數設為 "vector-ivf"
:
{
"createIndexes": "<collection_name>",
"indexes": [
{
"name": "<index_name>",
"key": {
"<path_to_property>": "cosmosSearch"
},
"cosmosSearchOptions": {
"kind": "vector-ivf",
"numLists": <integer_value>,
"similarity": "<string_value>",
"dimensions": <integer_value>
}
}
]
}
欄位 | 類型 | 描述 |
---|---|---|
index_name |
string | 索引的唯一名稱。 |
path_to_property |
string | 包含向量的屬性的路徑。 此路徑可以是最上層屬性或屬性的點標記法路徑。 如果使用點標記法路徑,則所有非分葉元素都不能是陣列。 向量必須是要編製索引的 number[] ,並在向量搜尋結果中予以傳回。 |
kind |
string | 要建立的向量索引類型。 選項為 vector-ivf 和 vector-hnsw : 注意 vector-ivf 在所有叢集層上可用,vector-hnsw 在 M40 叢集層及更高層上可用。 |
numLists |
整數 | 這個整數是反向檔案 (IVF) 索引用來將向量資料分組的叢集數目。 建議將 numLists 設定為 documentCount/1000 (最多 1 百萬個文件) 和 sqrt(documentCount) (超過 1 百萬個文件)。 使用 1 的 numLists 值類似執行暴力密碼破解搜尋,而其效能有限。 |
similarity |
字串 | 與索引搭配使用的相似度計量。 可能的選項是 COS (餘弦距離)、L2 (歐幾里得距離) 和 IP (內積)。 |
dimensions |
整數 | 向量相似度的維度數目。 所支援維度數目上限為 2000 。 |
重要
正確地設定 numLists 參數對達到良好的精確度和效能十分重要。 建議將 numLists
設定為 documentCount/1000
(最多 1 百萬個文件) 和 sqrt(documentCount)
(超過 1 百萬個文件)。
隨著資料庫中的項目數成長,您應該將 numLists 調整為較大的值,以達到向量搜尋的良好延遲效能。
如果您正在實驗新的情節,或建立小型示範,則可以從將 numLists
設定為 1
開始,以在所有向量上執行暴力密碼破解搜尋。 這應該會為您提供向量搜尋的最精確結果,不過,請注意,搜尋速度和延遲將會變慢。 初始設定之後,您應該繼續使用上述指導來微調 numLists
參數。
使用 IVF 來執行向量搜尋
若要執行向量搜尋,請在 MongoDB 查詢中使用 $search
彙總管線階段。 若要使用 cosmosSearch
索引,請使用新的 cosmosSearch
運算子。
{
{
"$search": {
"cosmosSearch": {
"vector": <query_vector>,
"path": "<path_to_property>",
"k": <num_results_to_return>,
},
"returnStoredSource": True }},
{
"$project": { "<custom_name_for_similarity_score>": {
"$meta": "searchScore" },
"document" : "$$ROOT"
}
}
}
若要擷取相似度分數 (searchScore
) 以及向量搜尋所找到的文件,請使用 $project
運算子來包括 searchScore
,並將其重新命名為結果中的 <custom_name_for_similarity_score>
。 然後,文件也會投影為巢狀物件。 請注意,相似度分數是使用向量索引中所定義的計量來計算。
重要
向量必須是要編製索引的 number[]
。 使用另一種類型 (例如 double[]
) 可防止將文件編製索引。 在向量搜尋的結果中,將不會傳回未編製索引的文件。
使用 HNSW 索引的範例。
下列範例顯示如何編製向量的索引、新增具有向量屬性的文件、執行向量搜尋,以及擷取索引設定。
use test;
db.createCollection("exampleCollection");
db.runCommand({
"createIndexes": "exampleCollection",
"indexes": [
{
"name": "VectorSearchIndex",
"key": {
"contentVector": "cosmosSearch"
},
"cosmosSearchOptions": {
"kind": "vector-hnsw",
"m": 16,
"efConstruction": 64,
"similarity": "COS",
"dimensions": 3
}
}
]
});
此命令會針對指定集合 exampleCollection
中所儲存文件內的 contentVector
屬性來建立 HNSW 索引。 cosmosSearchOptions
屬性指定 HNSW 向量索引的參數。 如果您的文件具有巢狀屬性中所儲存的向量,則您可以使用點標記法路徑來設定此屬性。 例如,如果 contentVector
是 text
的子屬性,則您可能會使用 text.contentVector
。
將向量新增至資料庫
若要將向量新增至資料庫的集合,您需要先使用自己的模型、Azure OpenAI 內嵌或另一個 API (例如 Hugging Face on Azure) 來建立內嵌。 在此範例中,透過範例內嵌來新增文件:
db.exampleCollection.insertMany([
{name: "Eugenia Lopez", bio: "Eugenia is the CEO of AdvenureWorks.", vectorContent: [0.51, 0.12, 0.23]},
{name: "Cameron Baker", bio: "Cameron Baker CFO of AdvenureWorks.", vectorContent: [0.55, 0.89, 0.44]},
{name: "Jessie Irwin", bio: "Jessie Irwin is the former CEO of AdventureWorks and now the director of the Our Planet initiative.", vectorContent: [0.13, 0.92, 0.85]},
{name: "Rory Nguyen", bio: "Rory Nguyen is the founder of AdventureWorks and the president of the Our Planet initiative.", vectorContent: [0.91, 0.76, 0.83]},
]);
執行向量搜尋
繼續進行最後一個範例,建立另一個向量 queryVector
。 向量搜尋會測量文件 contentVector
路徑中 queryVector
與向量之間的距離。 您可以設定 k
參數來設定搜尋所傳回的結果數目,這裡設定為 2
。 您也可以設定 efSearch
,它是一個控制候選向量清單大小的整數。 較高的值可能會改善精確度,但搜尋速度因此會變慢。 這是選擇性參數,預設值為 40。
const queryVector = [0.52, 0.28, 0.12];
db.exampleCollection.aggregate([
{
"$search": {
"cosmosSearch": {
"vector": "queryVector",
"path": "contentVector",
"k": 2,
"efSearch": 40
},
}
}
}
]);
在此範例中,透過 Mongo 殼層,使用 queryVector
作為輸入來執行向量搜尋。 此搜尋結果是兩個項目的清單,而這些項目與查詢向量最為類似,即依其相似度分數排序。
[
{
similarityScore: 0.9465376,
document: {
_id: ObjectId("645acb54413be5502badff94"),
name: 'Eugenia Lopez',
bio: 'Eugenia is the CEO of AdvenureWorks.',
vectorContent: [ 0.51, 0.12, 0.23 ]
}
},
{
similarityScore: 0.9006955,
document: {
_id: ObjectId("645acb54413be5502badff97"),
name: 'Rory Nguyen',
bio: 'Rory Nguyen is the founder of AdventureWorks and the president of the Our Planet initiative.',
vectorContent: [ 0.91, 0.76, 0.83 ]
}
}
]
取得向量索引定義
若要從集合中擷取向量索引定義,請使用 listIndexes
命令:
db.exampleCollection.getIndexes();
在此範例中,會傳回 vectorIndex
,其中包含已用來建立索引的所有 cosmosSearch
參數:
[
{ v: 2, key: { _id: 1 }, name: '_id_', ns: 'test.exampleCollection' },
{
v: 2,
key: { contentVector: 'cosmosSearch' },
name: 'vectorSearchIndex',
cosmosSearch: {
kind: 'vector-hnsw',
m: 40,
efConstruction: 64,
similarity: 'COS',
dimensions: 3
},
ns: 'test.exampleCollection'
}
]
使用 IVF 索引的範例
反轉檔案 (IVF) 索引是一種將向量組織成叢集的方法。 在向量搜尋期間,首先將查詢向量與這些叢集的中心進行比較。 然後在中心最接近查詢向量的叢集內進行搜尋。
numList
參數決定要建立叢集的數量。 單一叢集意味著搜尋是針對資料庫中的所有向量進行的,類似於強力搜尋或 kNN 搜尋。 此設定提供最高的準確度,但也提供最高的延遲。
增加 numLists
值會產生更多叢集,每個叢集包含較少的向量。 例如,如果是 numLists=2
,則每個叢集比 numLists=3
包含更多向量,依此類推。 每個叢集更少的向量可以加快搜尋速度 (更低的延遲,更高的每秒查詢次數)。 但是,這會增加遺失資料庫中與查詢向量最相似的向量的可能性。 這是由於叢集的不完美性質,搜尋可能集中在一個叢集上,而實際的「最接近」向量駐留在不同的叢集中。
nProbes
參數控制要搜尋的叢集數量。 預設情況下,它設定為 1,這表示它僅搜尋中心最接近查詢向量的叢集。 增加此值允許搜尋覆蓋更多叢集,從而提高準確性,但隨著搜尋更多叢集和向量,也會增加延遲 (從而減少每秒查詢)。
下列範例顯示如何編製向量的索引、新增具有向量屬性的文件、執行向量搜尋,以及擷取索引設定。
建立向量索引
use test;
db.createCollection("exampleCollection");
db.runCommand({
createIndexes: 'exampleCollection',
indexes: [
{
name: 'vectorSearchIndex',
key: {
"vectorContent": "cosmosSearch"
},
cosmosSearchOptions: {
kind: 'vector-ivf',
numLists: 3,
similarity: 'COS',
dimensions: 3
}
}
]
});
此命令會針對指定集合 exampleCollection
中所儲存文件內的 vectorContent
屬性來建立 vector-ivf
索引。 cosmosSearchOptions
屬性指定 IVF 向量索引的參數。 如果您的文件具有巢狀屬性中所儲存的向量,則您可以使用點標記法路徑來設定此屬性。 例如,如果 vectorContent
是 text
的子屬性,則您可能會使用 text.vectorContent
。
將向量新增至資料庫
若要將向量新增至資料庫的集合,您需要先使用自己的模型、Azure OpenAI 內嵌或另一個 API (例如 Hugging Face on Azure) 來建立內嵌。 在此範例中,透過範例內嵌來新增文件:
db.exampleCollection.insertMany([
{name: "Eugenia Lopez", bio: "Eugenia is the CEO of AdvenureWorks.", vectorContent: [0.51, 0.12, 0.23]},
{name: "Cameron Baker", bio: "Cameron Baker CFO of AdvenureWorks.", vectorContent: [0.55, 0.89, 0.44]},
{name: "Jessie Irwin", bio: "Jessie Irwin is the former CEO of AdventureWorks and now the director of the Our Planet initiative.", vectorContent: [0.13, 0.92, 0.85]},
{name: "Rory Nguyen", bio: "Rory Nguyen is the founder of AdventureWorks and the president of the Our Planet initiative.", vectorContent: [0.91, 0.76, 0.83]},
]);
執行向量搜尋
若要執行向量搜尋,請在 MongoDB 查詢中使用 $search
彙總管線階段。 若要使用 cosmosSearch
索引,請使用新的 cosmosSearch
運算子。
{
{
"$search": {
"cosmosSearch": {
"vector": <vector_to_search>,
"path": "<path_to_property>",
"k": <num_results_to_return>,
},
"returnStoredSource": True }},
{
"$project": { "<custom_name_for_similarity_score>": {
"$meta": "searchScore" },
"document" : "$$ROOT"
}
}
}
若要擷取相似度分數 (searchScore
) 以及向量搜尋所找到的文件,請使用 $project
運算子來包括 searchScore
,並將其重新命名為結果中的 <custom_name_for_similarity_score>
。 然後,文件也會投影為巢狀物件。 請注意,相似度分數是使用向量索引中所定義的計量來計算。
使用 $search 來查詢向量和向量距離 (也稱為相似度分數)
繼續進行最後一個範例,建立另一個向量 queryVector
。 向量搜尋會測量文件 vectorContent
路徑中 queryVector
與向量之間的距離。 您可以設定 k
參數來設定搜尋所傳回的結果數目,這裡設定為 2
。 您也可以設定 nProbes
,這是一個整數,可控制每個搜尋中檢查的鄰近叢集數目。 較高的值可能會改善精確度,但搜尋速度因此會變慢。 這是預設值為 1 的選用參數,而且不能大於向量索引中所指定的 numLists
值。
const queryVector = [0.52, 0.28, 0.12];
db.exampleCollection.aggregate([
{
$search: {
"cosmosSearch": {
"vector": queryVector,
"path": "vectorContent",
"k": 2
},
"returnStoredSource": true }},
{
"$project": { "similarityScore": {
"$meta": "searchScore" },
"document" : "$$ROOT"
}
}
]);
在此範例中,透過 Mongo 殼層,使用 queryVector
作為輸入來執行向量搜尋。 此搜尋結果是兩個項目的清單,而這些項目與查詢向量最為類似,即依其相似度分數排序。
[
{
similarityScore: 0.9465376,
document: {
_id: ObjectId("645acb54413be5502badff94"),
name: 'Eugenia Lopez',
bio: 'Eugenia is the CEO of AdvenureWorks.',
vectorContent: [ 0.51, 0.12, 0.23 ]
}
},
{
similarityScore: 0.9006955,
document: {
_id: ObjectId("645acb54413be5502badff97"),
name: 'Rory Nguyen',
bio: 'Rory Nguyen is the founder of AdventureWorks and the president of the Our Planet initiative.',
vectorContent: [ 0.91, 0.76, 0.83 ]
}
}
]
取得向量索引定義
若要從集合中擷取向量索引定義,請使用 listIndexes
命令:
db.exampleCollection.getIndexes();
在此範例中,會傳回 vectorIndex
,其中包含已用來建立索引的所有 cosmosSearch
參數:
[
{ v: 2, key: { _id: 1 }, name: '_id_', ns: 'test.exampleCollection' },
{
v: 2,
key: { vectorContent: 'cosmosSearch' },
name: 'vectorSearchIndex',
cosmosSearch: {
kind: 'vector-ivf',
numLists: 3,
similarity: 'COS',
dimensions: 3
},
ns: 'test.exampleCollection'
}
]
已篩選的向量搜尋 (預覽)
現在您可以使用任何支援的查詢篩選條件 (例如 $lt
, $lte
, $eq
, $neq
, $gte
, $gt
, $in
, $nin
及 $regex
)執行向量搜尋。 在 Azure 訂用帳戶的 [預覽功能] 索引標籤中啟用「篩選向量搜尋」功能。 在這裡深入瞭解預覽功能。
首先,除了向量索引之外,您還需要定義篩選的索引。 例如,您可以在屬性上定義篩選索引
db.runCommand({
"createIndexes": "<collection_name",
"indexes": [ {
"key": {
"<property_to_filter>": 1
},
"name": "<name_of_filter_index>"
}
]
});
接下來,您可以將 "filter"
字詞新增至向量搜尋,如下所示。 在此範例中,篩選正在尋找 "title"
屬性不在 ["not in this text", "or this text"]
清單中的文件。
db.exampleCollection.aggregate([
{
'$search': {
"cosmosSearch": {
"vector": "<query_vector>",
"path": <path_to_vector>,
"k": num_results,
"filter": {<property_to_filter>: {"$nin": ["not in this text", "or this text"]}}
},
"returnStoredSource": True }},
{'$project': { 'similarityScore': { '$meta': 'searchScore' }, 'document' : '$$ROOT' }
}
]);
重要
在預覽期間,篩選的向量搜尋可能需要您調整向量索引參數,以達到更高的精確度。 例如,在使用 HNSW 時增加 m
、efConstruction
或 efSearch
,或使用 IVF 時,numLists
或 nProbes
可能會導致更好的結果。 您應該先測試您的設定,再使用以確保結果令人滿意。
使用 LLM 協調流程工具
搭配使用向量資料庫與語意核心
使用語意核心以利協調從 Azure Cosmos DB for MongoDB vCore 和 LLM 中擷取的資訊。 在這裡深入了解。
搭配使用向量資料庫與 LangChain
使用 LangChain 來協調從 Azure Cosmos DB for MongoDB vCore 和 LLM 中擷取的資訊。 在這裡深入了解。
使用作為語意快取與 LangChain
使用適用於 MongoDB 的 LangChain 和 Azure Cosmos DB (vCore) 協調語意快取,使用先前重新排列的 LLM 回應來節省 LLM API 成本,並減少回應延遲。 在這裡深入了解
功能和限制
- 支援的距離計量:L2 (歐幾里得)、內積和餘弦。
- 支援的索引編製方法:IVFFLAT (GA) 和 HSNW (預覽)
- 對大小上限為 2,000 個維度的向量進行編製索引。
- 一個路徑只會有一個向量套用編製索引。
- 一個向量路徑只能建立一個索引。
摘要
本指南示範如何建立向量索引、新增具有向量資料的文件、執行相似度搜尋,以及擷取索引定義。 透過使用我們的整合向量資料庫,您可以有效率地儲存、編製索引和查詢 Azure Cosmos DB for MongoDB vCore 虛擬核心中的高維度向量資料。 它可讓您透過向量內嵌來解除鎖定資料的完整潛力,並讓您能夠建置更精確、具效率且功能強大的應用程式。
相關內容
- .NET RAG 模式零售參考解決方案
- .NET 教學課程 - 食譜聊天機器人
- C# RAG 模式 - 整合 Open AI 服務與 Cosmos
- Python RAG 模式 - Azure 產品聊天機器人
- Python 筆記本教學課程 - 透過 LangChain 進行向量資料庫整合
- Python 筆記本教學課程 - 透過 LangChain 進行 LLM 快取整合
- Python - LlamaIndex 整合
- Python - 語意核心記憶體整合