3.2版中的新功能。
部分索引仅索引集合中符合指定过滤器表达式的文档。通过索引集合中文档的子集,部分索引具有较低的存储需求,并降低了索引创建和维护的性能成本。
要创建partial
索引,请将该
db.collection.createIndex()
方法与
partialFilterExpression
选项一起使用。该partialFilterExpression
选项接受使用以下命令指定过滤条件的文档:
例如,以下操作创建一个复合索引,该索引仅索引rating
字段大于5 的文档。
您可以partialFilterExpression
为所有MongoDB 索引类型指定一个选项
。
如果使用索引导致结果集不完整,则MongoDB不会将部分索引用于查询或排序操作。
若要使用部分索引,查询必须包含过滤器表达式(或指定过滤器表达式的子集的修改后的过滤器表达式)作为其查询条件的一部分。
例如,给定以下索引:
由于查询谓词包含与由索引过滤器表达式匹配的文档子集匹配的条件,因此以下查询可以使用索引:rating: { $gte: 8 }
rating: { $gt: 5
}
但是,以下查询不能在cuisine
字段上使用部分索引,
因为使用索引会导致结果集不完整。具体来说,查询谓词包括条件,
而索引具有filter 。也就是说,查询匹配的文档(例如,评级等于1的意大利餐厅)多于被索引的文档。rating: { $lt: 8 }
rating: { $gt:
5 }
{ cuisine: "Italian", rating: { $lt: 8 }
}
同样,以下查询不能使用部分索引,因为查询谓词不包含过滤器表达式,并且使用索引将返回不完整的结果集。
sparse
索引比较¶小费
部分索引代表稀疏索引提供的功能的超集,应优先于稀疏索引。
与稀疏索引索引相比,部分索引提供了一种更具表达性的机制 来指定要对哪些文档建立索引。
稀疏索引仅根据索引字段的存在来选择要索引的文档,对于复合索引,则仅根据索引字段的存在来进行索引。
部分索引根据指定的过滤器确定索引条目。该过滤器可以包含除索引键以外的其他字段,并且可以指定除存在检查以外的条件。例如,部分索引可以实现与稀疏索引相同的行为:
此部分索引支持与name
字段上的稀疏索引相同的查询
。
但是,部分索引还可以在索引键以外的其他字段上指定过滤器表达式。例如,以下操作创建一个局部索引,其中索引在name
字段上,而过滤器表达式在email
字段上:
为了使查询优化器选择此部分索引,查询谓词必须在name
字段上包含条件以及在字段上包含非空匹配email
。
例如,以下查询可以使用索引,因为它既包含name
字段上的条件,又包含字段上的非空匹配
email
:
但是,以下查询无法使用索引,因为它在email
字段上包含空匹配,这是过滤器表达式不允许的
:{ email: { $exists: true } }
在MongoDB中,您不能创建仅在选项上有所不同的多个索引版本。因此,您不能创建仅因过滤器表达式而不同的多个部分索引。
您不能同时指定partialFilterExpression
选项和sparse
选项。
MongoDB 3.0或更早版本不支持部分索引。要使用部分索引,您必须使用MongoDB 3.2或更高版本。对于分片群集或副本集,所有节点必须为3.2或更高版本。
_id
索引不能是部分索引。
分片键索引不能是部分索引。
考虑一个restaurants
包含类似于以下内容的文档的集合
您可以在borough
和cuisine
字段上添加部分索引,仅选择索引rating.grade
字段为的文档A
:
然后,对restaurants
集合的以下查询使用部分索引返回布朗克斯中rating.grade
等于的餐厅A
:
但是,以下查询不能使用部分索引,因为查询表达式不包含该rating.grade
字段:
部分索引仅索引集合中符合指定过滤器表达式的文档。如果同时指定
partialFilterExpression
和约束,则唯一约束仅适用于满足过滤器表达式的文档。如果文档不满足过滤条件,则具有唯一性约束的部分索引不会阻止不符合唯一性约束的文档的插入。
例如,一个集合users
包含以下文档:
以下操作将创建一个索引,该索引指定字段上的唯一约束username
和部分过滤器表达式。age: { $gte: 21 }
该索引可防止插入以下文档,因为文档已经存在且具有指定的用户名,并且age
字段大于21
:
但是,允许以下具有重复用户名的文档,因为唯一约束仅适用于age
大于或等于21的文档。