在 Azure Cosmos DB for MongoDB 虛擬核心中管理索引編制
適用於: MongoDB 虛擬核心
索引是透過提供快速存取集錦內欄位來增強資料擷取速度的結構。 其運作方式是建立一組已排序集錦的資料指標,通常是根據索引鍵字段。 Azure Cosmos DB for MongoDB 虛擬核心會利用多個內容中的索引,包括查詢下推、唯一條件約束和分區化。
重要
[_id] 字段是預設唯一編製索引的字段,字段的大小上限可以是 2 KB
。 建議您根據查詢篩選和述詞新增其他索引,以最佳化效能。
索引類型
為了簡單起見,我們以採用下列設定的部落格應用程式為例:
- 資料庫名稱:
cosmicworks
- 集合名稱:
products
此範例應用程式會將文章儲存為具有下列結構的文件: 所有引述的範例都會進一步利用這個集錦的結構。
{
"_id": ObjectId("617a34e7a867530bff1b2346"),
"title": "Azure Cosmos DB - A Game Changer",
"content": "Azure Cosmos DB is a globally distributed, multi-model database service.",
"author": {lastName: "Doe", firstName: "John"},
"category": "Technology",
"launchDate": ISODate("2024-06-24T10:08:20.000Z"),
"published": true
}
單一欄位索引
單一欄位索引會儲存集錦中單一欄位的資訊。 單一欄位索引的排列順序並不重要。 _id
欄位預設會維持索引。
Azure Cosmos DB for MongoDB 虛擬核心支援以下索引子和索引子屬性
- 最上層檔欄位。
- 內嵌文件。
- 內嵌文件內的欄位。
下列命令會在欄位 author
上建立單一欄位索引子,而下列命令會在內嵌欄位 firstName
上建立它。
use cosmicworks
db.products.createIndex({"author": 1})
// indexing embedded property
db.products.createIndex({"author.firstName": -1})
一個查詢可以使用多個單一欄位索引 (如果可用的話)。
注意
Azure Cosmos DB for MongoDB 虛擬核心允許在集錦上建立最多 64 個索引子。 視層級而定,我們可以依要求規劃最多 300 個索引的延伸項目。
複合索引
複合索引可讓您根據檔內的多個字段,有效率地查詢和排序,以改善資料庫效能。 此最佳化可減少掃描整個集錦、加速資料擷取和組織的需求。
下列命令會按相反排序次序在欄位 author
和 launchDate
上建立複合索引。
use cosmicworks
db.products.createIndex({"author":1, "launchDate":-1})
Order
的欄位會影響索引的選擇性或使用率。 查詢 find
不會利用建立的索引。
use cosmicworks
db.products.find({"launchDate": {$gt: ISODate("2024-06-01T00:00:00.000Z")}})
限制
- 複合索引子內最多 32 個字段\路徑。
部分索引
具有相關聯查詢篩選條件的索引,描述何時在索引子中產生字詞。
use cosmicworks
db.products.createIndex (
{ "author": 1, "launchDate": 1 },
{ partialFilterExpression: { "launchDate": { $gt: ISODate("2024-06-24T10:08:20.000Z") } } }
)
限制
- 部分索引不支援
ORDER BY
或UNIQUE
除非篩選條件限定。
文字索引
文字索引屬於特殊資料結構,可最佳化以文字為基礎的查詢,使其更快速且更有效率。
使用 createIndex
方法搭配 text
選項,在 title
欄位上建立文字索引。
use cosmicworks;
db.products.createIndex({ title: "text" })
注意
雖然每個集錦只能定義一個文字索引,但 Azure Cosmos DB for MongoDB 虛擬核心可讓您在多個欄位組合上建立文字索引,而能夠在文件中的不同欄位間執行文字搜尋。
設定文字索引選項
Azure Cosmos DB for MongoDB 虛擬核心中的文字索引附有數個可自訂行為的選項。 例如,您可以指定文字分析的語言、設定權數以排定特定欄位的優先順序,以及設定不區分大小寫的搜尋。 以下是使用選項建立文字索引的範例:
建立索引,以支援對
title
和content
欄位的搜尋 (支援英文)。 此外,為title
欄位指派較高的權數,以在搜尋結果中提高其優先順序。use cosmicworks db.products.createIndex( { title: "text", content: "text" }, { default_language: "english", weights: { title: 10, content: 5 }, caseSensitive: false } )
注意
當用戶端使用 "Cosmos DB" 一詞執行文字搜尋查詢時,集錦中每份文件的分數將會根據該字詞在 "title" 和 "content" 欄位中存在與否及其頻率來計算,而 "title" 欄位由於權數較高,因此會有較高的重要性。
使用文字索引執行文字搜尋
建立文字索引後,您可以在查詢中使用「文字」運算子來執行文字搜尋。 文字運算子會採用搜尋字串,並將其與文字索引比對以尋找相關的文件。
執行片語
Cosmos DB
的文字搜尋。use cosmicworks db.products.find( { $text: { $search: "Cosmos DB" } } )
選擇性地在查詢中使用
$meta
投射運算子與textScore
欄位以查看權數use cosmicworks db.products.find( { $text: { $search: "Cosmos DB" } }, { score: { $meta: "textScore" } } )
限制
- 一個集合只能定義一個文字索引。
- 文字索引支援簡單的文字搜尋,且不提供規則運算式搜尋之類的進階搜尋功能。
- 排序作業無法使用 MongoDB 中的文字索引順序。
- 不支援將 Hint() 與使用 $text 運算式的查詢搭配使用。
- 相較於其他索引類型,文字索引可能相對較大,因而耗用較大的儲存空間。
萬用字元索引
在單一欄位上編製索引,為 下方 field
的所有路徑編製索引,但不包括相同層級的其他欄位。 例如,針對下列範例文件
{
"children":
{
"familyName": "Merriam",
"pets": { "details": {“name”: "Goofy", ”age”: 3} }
}
}
在 { "pets.$**": 1 } 上建立索引,在詳細資料和子文件屬性上建立索引,但不會在「familyName」上建立索引。
限制
- 萬用字元索引不支援唯一索引。
- 除非篩選只包含通配符中存在的路徑,否則萬用字元索引不支援下
ORDER BY
推 (因為它們不會為未定義的元素編製索引) - 複合通配符索引只能有
one
萬用字元索引和one
或更多萬用字元索引。{ "pets.$**": 1, “familyName”: 1 }
地理空間索引
地理空間索引支援對儲存為 GeoJSON 物件或舊版座標組的資料進行查詢。 您可以使用地理空間索引來改善地理空間資料查詢的效能,或執行特定地理空間查詢。
Azure Cosmos DB for MongoDB 虛擬核心提供兩種類型的地理空間索引:
- 2dsphere Indexes,可支持解譯器球體上幾何的查詢。
- 2d Indexes,可支持解譯器球體上幾何的查詢。
2d 索引
2d 索引僅支援舊版座標組樣式來儲存地理空間資料。
使用 createIndex
方法搭配 2d
選項,在 location
欄位上建立地理空間索引。
db.places.createIndex({ "location": "2d"});
限制
- 只有
one
位置欄位可以是索引的2d
一部分,而其他one
非地理空間欄位只能是索引的compound 2d
一部分db.places.createIndex({ "location": "2d", "non-geospatial-field": 1 / -1 })
2dsphere 索引
2dsphere
索引支持類似地球的球體上的地理空間查詢。 它可以支援 GeoJSON 物件或舊版座標組。 2dSphere
索引會使用儲存資料的 GeoJSON 樣式,如果遇到舊版點,則會轉換成 GeoJSON 點。
使用 createIndex
方法搭配 2dsphere
選項,在 location
欄位上建立地理空間索引。
db.places.createIndex({ "location": "2dsphere"});
2dsphere
索引允許在多個地理空間和多個非地理空間資料欄位上建立索引。
db.places.createIndex({ "location": "2d", "non-geospatial-field": 1 / -1, ... "more non-geospatial-field": 1 / -1 })
限制
不支援使用一般索引和地理空間索引的複合索引。 建立其中一個地理空間索引會導致錯誤。
// Compound Regular & 2dsphere indexes are not supported yet db.collection.createIndex({a: 1, b: "2dsphere"}) // Compound 2d indexes are not supported yet db.collection.createIndex({a: "2d", b: 1})
具有漏洞的多邊形無法運作。 插入具有洞的多邊形並不受限,但
$geoWithin
案例的查詢失敗:如果查詢本身具有具有漏洞的多邊形
coll.find( { "b": { "$geoWithin": { "$geometry": { "coordinates": [ [ [ 0, 0], [0, 10], [10, 10],[10,0],[0, 0] ], [ [5, 5], [8, 5], [ 8, 8], [ 5, 8], [ 5, 5] ] ], "type": "Polygon" } } } }) // MongoServerError: $geoWithin currently doesn't support polygons with holes
如果有任何未篩選的文件具有具有漏洞的多邊形。
[mongos] test> coll.find() [ { _id: ObjectId("667bf7560b4f1a5a5d71effa"), b: { type: 'Polygon', coordinates: [ [ [ 0, 0 ], [ 0, 10 ], [ 10, 10 ], [ 10, 0 ], [ 0, 0 ] ], [ [ 5, 5 ], [ 8, 5 ], [ 8, 8 ], [ 5, 8 ], [ 5, 5 ] ] ] } } ] // MongoServerError: $geoWithin currently doesn't support polygons with holes
key
欄位在使用 時geoNear
是必要的。[mongos] test> coll.aggregate([{ $geoNear: { $near: { "type": "Point", coordinates: [0, 0] } } }]) // MongoServerError: $geoNear requires a 'key' option as a String