

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 部分索引
<a name="partial-index"></a>

部分索引會索引集合中符合指定篩選條件的文件。Amazon DocumentDB 5.0 執行個體型叢集支援部分索引功能。

**Topics**
+ [建立部分索引](#create-partial-index)
+ [支援的運算子](#partial-index-operators)
+ [使用部分索引查詢](#partial-index-query)
+ [部分索引功能](#partial-index-functionalities)
+ [部分索引限制](#partial-index-limitations)

## 建立部分索引
<a name="create-partial-index"></a>

若要建立部分索引，請使用 `createIndex()`方法搭配 `partialFilterExpression`選項。例如，下列操作會在訂單集合中建立唯一的複合索引，該索引會將具有 的文件編製索引，`OrderID`並將 `isDelivered` 欄位為 true：

```
db.orders.createIndex(
  {"category": 1, "CustomerId": 1, "OrderId": 1}, 
  {"unique": true, "partialFilterExpression": 
    {"$and": [
      {"OrderId": {"$exists": true}}, 
      {"isDelivered": {"$eq": false}}
    ]}
  }
)
```

## 支援的運算子
<a name="partial-index-operators"></a>


+ **\$1eq**
+ **\$1exists**
+ **\$1and** （僅限最上層）
+ **\$1gt/\$1gte/\$1lt/\$1lte** （索引掃描僅在篩選條件在查詢中述詞，完全符合部分篩選條件表達式時使用） （請參閱限制）

## 使用部分索引查詢
<a name="partial-index-query"></a>

下列查詢模式可以使用部分索引：
+ 查詢述詞完全符合部分索引篩選條件表達式：

  ```
  db.orders.find({"$and": [
      {"OrderId": {"$exists": true}}, 
      {"isDelivered": {"$eq": false}}
    ]}).explain()
  ```
+ 查詢篩選條件的預期結果是部分篩選條件的邏輯子集：

  ```
  db.orders.find({"$and": [
      {"OrderId": {"$exists": true}}, 
      {"isDelivered": {"$eq": false}},
      {"OrderAmount": {"$eq": "5"}}
    ]}).explain()
  ```
+ 查詢的子述詞可以與其他索引搭配使用：

  ```
  db.orders.createIndex({"anotherIndex":1})
  db.orders.find({ "$or": [
        {"$and": [
          {"OrderId": {"$exists": true}}, 
          {"isDelivered": {"$eq": false}}
        ]},
        {"anotherIndex": {"$eq": 5}}
      ]
    }).explain()
  ```

**注意**  
如果這麼做有效率，查詢規劃器可以選擇使用集合掃描，而不是索引掃描。對於會傳回大部分集合的非常小型集合或查詢，通常會看到這種情況。

## 部分索引功能
<a name="partial-index-functionalities"></a>

**列出部分索引**

使用 `getIndex`操作列出具有 partialFilterExpression 的部分索引。例如， 中發出的`getIndex`操作會列出具有索引鍵、名稱和 partialfilterExpressions 欄位的部分索引：

```
db.orders.getIndexes()
```

此範例會傳回下列輸出：

```
[
  {
    "v" : 4,
    "key" : {
      "_id" : 1
    },
    "name" : "_id_",
    "ns" : "ecommerceApp.orders"
  },
  {
    "v" : 4,
    "unique" : true,
    "key" : {
      "category" : 1,
      "" : 1,
      "CustomerId" : 1,
      "OrderId" : 1
    },
    "name" : "category_1_CustID_1_OrderId_1",
    "ns" : "ecommerceApp.orders",
    "partialFilterExpression" : {
      "$and" : [
        {"OrderId": {"$exists": true}}, 
        {"isDelivered": {"$eq": false}}
      ]
    }
  }
]
```

**相同 key：order 上的多個部分篩選條件表達式**

您可以為相同的欄位組合 (key：order) 建立不同的部分索引。這些索引必須具有不同的名稱。

```
db.orders.createIndex(
  {"OrderId":1},
  {
    name:"firstPartialIndex",
    partialFilterExpression:{"OrderId":{"$exists": true}}
  }
)
```

```
db.orders.createIndex(
  {"OrderId":1},
  {
    name:"secondPartialIndex",
    partialFilterExpression:{"OrderId":{"$gt": 1000}}
  }
)
```

執行 `getIndexes`操作以列出集合中的所有索引：

```
db.orders.getIndexes()
```

這些範例會傳回下列輸出：

```
[
  {
    "v" : 4,
    "key" : {
      "_id" : 1
    },
    "name" : "_id_",
    "ns" : "ecommerceApp.orders"
  },
  {
    "v" : 4,
    "key" : {
      "OrderId" : 1
    },
    "name" : "firstPartialIndex",
    "ns" : "ecommerceApp.orders",
    "partialFilterExpression" : {"OrderId":{"$exists": true}}
  },
  {
    "v" : 4,
    "key" : {
      "OrderId" : 1
    },
    "name" : "secondPartialIndex",
    "ns" : "ecommerceApp.orders",
    "partialFilterExpression" : {"OrderId":{"$gt": 1000}}
  }
]
```

**重要**  
索引名稱必須不同，且只能依名稱刪除。

**具有部分和 TTL 屬性的索引**

您也可以在建立索引期間同時指定 `partialFilterExpression` 和 `expireAfterSeconds`選項，以建立具有部分和 TTL 屬性的索引。這可讓您更進一步控制哪些文件現在已從集合中移除。

例如，您可能有一個 TTL 索引，可識別在特定期間後要刪除的文件。您現在可以提供使用部分索引選項刪除文件時的額外條件：

```
db.orders.createIndex(
    { "OrderTimestamp": 1 },
    {
        expireAfterSeconds: 3600 , 
        partialFilterExpression: { "isDelivered": { $eq: true } } 
    }
)
```

此範例會傳回下列輸出：

```
{
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 1,
        "numIndexesAfter" : 2,
        "ok" : 1,
        "operationTime" : Timestamp(1234567890, 1)
}
```

執行 `getIndexes`操作以列出集合中存在的索引：

```
db.orders.getIndexes()
[
    {
        "v" : 4,
        "key" : {
            "_id" : 1
        },
        "name" : "_id_",
        "ns" : "test.orders"
    }
```

此範例會傳回下列輸出：

```
[
    {
        "v": 4,
        "key": {
            "_id": 1
        },
        "name": "_id_",
        "ns": "ecommerceApp.orders"
    },
    {
        "v": 4,
        "key": {
            "OrderTimestamp": 1
        },
        "name": "OrderTimestamp_1",
        "ns": "ecommerceApp.orders",
        "partialFilterExpression": {
            "isDelivered": {
                "$eq": true
            }
        },
        "expireAfterSeconds": 3600
    }
]
```

## 部分索引限制
<a name="partial-index-limitations"></a>

下列限制適用於部分索引功能：
+ Amazon DocumentDB 中的不等式查詢只有在查詢篩選條件述詞完全符合 `partialFilterExpression`且具有相同資料類型時，才會使用部分索引。
**注意**  
甚至`$hint`無法用於強制上述案例使用 IXSCAN。

  在下列範例中， `partialFilterExpression` 只會套用至 ，`field1`但不會套用至 `field2`：

  ```
  db.orders.createIndex(
    {"OrderAmount": 1}, 
    {"partialFilterExpression": { OrderAmount : {"$gt" : 5}}}
  )
  
  db.orders.find({OrderAmount : {"$gt" : 5}}) // Will use partial index
  db.orders.find({OrderAmount : {"$gt" : 6}}) // Will not use partial index
  db.orders.find({OrderAmount : {"$gt" : Decimal128(5.00)}}) // Will not use partial index
  ```
+ 不支援`partialFilterExpression`具有陣列運算子的 。下列操作將產生錯誤：

  ```
  db.orders.createIndex(
    {"CustomerId":1},
    {'partialFilterExpression': {'OrderId': {'$eq': [1000, 1001, 1002]}}}
  )
  ```
+ partialFilterExpression 欄位不支援下列運算子：
  + `$all` （陣列運算子）
  + `$mod` （陣列運算子）
  + `$or`
  + `$xor`
  + `$not`
  + `$nor`
+ 篩選條件表達式和篩選條件的資料類型應相同。