部分索引 - Amazon DocumentDB
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

部分索引

部分索引对符合指定筛选条件的集合中的文档编制索引。基于实例的 Amazon DocumentDB 5.0 集群支持部分索引功能。

创建部分索引

要创建部分索引,请使用带partialFilterExpression选项createIndex()的方法。例如,以下操作在 orders 集合中创建一个唯一的复合索引,该索引为字段为 true OrderID 且该isDelivered字段为 true 的文档编制索引:

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

支持的运算符

  • $eq

  • $exists

  • $and(仅在顶层)

  • $gt/$gte/$lte/$lt e(仅当查询中的谓词过滤器与部分过滤器表达式完全匹配时才使用索引扫描)(参见限制)

使用部分索引进行查询

使用部分索引可以采用以下查询模式:

  • 查询谓词与部分索引筛选表达式完全匹配:

    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()
注意

如果有效的话,查询计划器可以选择使用集合扫描而不是索引扫描。这通常出现在非常小的集合或查询中,这些集合或查询会返回集合的很大一部分。

部分索引功能

列出部分索引

partialFilterExpression 使用getIndex操作列出部分索引。例如,中发出的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}} ] } } ]

同一个键上的多个部分过滤器表达式: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 属性的索引

您还可以通过在索引创建过程中同时指定和expireAfterSeconds选项来创建具有部分partialFilterExpression和 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 } ]

部分索引限制

以下限制适用于部分索引功能:

  • 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带数组运算符的 A。以下操作将生成错误:

    db.orders.createIndex( {"CustomerId":1}, {'partialFilterExpression': {'OrderId': {'$eq': [1000, 1001, 1002]}}} )
  • partialFilterExpression 字段中不支持以下运算符:

    • $all(数组运算符)

    • $mod(数组运算符)

    • $or

    • $xor

    • $not

    • $nor

  • 筛选表达式和筛选器的数据类型应相同。