共用方式為


在 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 個索引的延伸項目。

複合索引

複合索引可讓您根據檔內的多個字段,有效率地查詢和排序,以改善資料庫效能。 此最佳化可減少掃描整個集錦、加速資料擷取和組織的需求。

下列命令會按相反排序次序在欄位 authorlaunchDate 上建立複合索引。

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 BYUNIQUE 除非篩選條件限定。

文字索引

文字索引屬於特殊資料結構,可最佳化以文字為基礎的查詢,使其更快速且更有效率。

使用 createIndex 方法搭配 text 選項,在 title 欄位上建立文字索引。

use cosmicworks;

db.products.createIndex({ title: "text" })

注意

雖然每個集錦只能定義一個文字索引,但 Azure Cosmos DB for MongoDB 虛擬核心可讓您在多個欄位組合上建立文字索引,而能夠在文件中的不同欄位間執行文字搜尋。

設定文字索引選項

Azure Cosmos DB for MongoDB 虛擬核心中的文字索引附有數個可自訂行為的選項。 例如,您可以指定文字分析的語言、設定權數以排定特定欄位的優先順序,以及設定不區分大小寫的搜尋。 以下是使用選項建立文字索引的範例:

  • 建立索引,以支援對 titlecontent 欄位的搜尋 (支援英文)。 此外,為 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 案例的查詢失敗:

    1. 如果查詢本身具有具有漏洞的多邊形

      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
      
    2. 如果有任何未篩選的文件具有具有漏洞的多邊形。

      [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
      
    3. key 欄位在使用 時 geoNear 是必要的。

       [mongos] test> coll.aggregate([{ $geoNear: { $near: { "type": "Point", coordinates: [0, 0] } } }])
      
       // MongoServerError: $geoNear requires a 'key' option as a String
      

下一步