部分索引
在本页面
新版本3.2.
部分索引只索引集合中满足指定筛选器表达式的文档。通过索引集合中文档的子集,部分索引可以降低存储需求,并降低创建和维护索引的性能成本。
创建部分索引
使用db.collection.createIndex()方法和**'partialFilterExpression'选项。“partialFilterExpression”**选项接受指定筛选条件的文档,使用:
等式表达式(即 运算符),
field: value
$eq
$exists: true
表达,$type
表达式,$and
只在顶层操作符
例如,下面的操作创建一个复合索引,该索引只对“rating”字段大于5的文档进行索引。
你可以为所有的MongoDB索引类型,指定一个partialFilterExpression选项.
行为
查询范围
如果使用索引导致结果集不完整,则MongoDB不会将部分索引用于查询或排序操作。
若要使用部分索引,查询必须将筛选器表达式(或指定筛选器表达式子集的经过修改的筛选器表达式)作为其查询条件的一部分。
例如,给定以下索引:
下面的查询可以使用索引,因为查询谓词包含条件“rating: {$gte: 8}”
,它匹配索引筛选器表达式“rating: {$gt: 5}”
匹配的文档子集:
但是,以下查询不能在**“cuisine”**字段上使用部分索引,因为使用该索引会导致不完整的结果集。具体来说,查询谓词包括条件rating: {$lt: 8}
,而索引有过滤器rating: {$gt: 5}
。也就是说,查询{cuisine: "Italian", rating: {$lt: 8}}
匹配的文档(例如,一家评级为1的意大利餐厅)比编入索引的文档更多。
类似地,以下查询不能使用部分索引,因为查询谓词不包括筛选器表达式,并且使用索引将返回不完整的结果集。
与“sparse”索引进行比较
提示
部分索引代表sparse索引提供的功能的超集,应优先于sparse索引。
部分索引提供了一种比sparse索引索引更有表现力的机制来指定索引哪些文档。
Sparse索引根据索引字段的存在性选择文档进行索引,对于复合索引则根据索引字段的存在性选择文档。
部分索引根据指定的筛选器确定索引项。过滤器可以包括索引键以外的字段,并可以指定条件,而不仅仅是存在检查。例如,部分索引可以实现与sparse索引相同的行为:
此部分索引支持与**“name”字段上的sparse**索引相同的查询。
但是,部分索引还可以在索引键以外的字段上指定筛选器表达式。例如,下面的操作创建了一个部分索引,其中索引在name字段上,但是过滤器表达式在email字段上:
为了让查询优化器选择此部分索引,查询谓词必须包含**“name”字段上的条件,以及“email”字段上的非空**匹配。
例如,下面的查询可以使用索引,因为它包括**' name '字段上的条件和' email '**字段上的非空匹配:
但是,以下查询不能使用索引,因为它在**“email”字段上包含了一个null**匹配,这是过滤器表达式{email: {$exists: true}}
不允许的:
限制
在MongoDB中,您不能创建仅在选项上有所不同的多个索引版本。因此,您不能创建仅因过滤器表达式而不同的多个部分索引。
您不能同时指定partialFilterExpression
选项和sparse
选项。
MongoDB 3.0或更早版本不支持部分索引。要使用部分索引,必须使用MongoDB 3.2或更高版本。对于分片集群或复制集,所有节点必须是版本3.2或更高。
_id
索引不能是部分索引。
分片键索引不能是部分索引。
例子
在集合上创建部分索引
考虑包含类似于以下文档的集合restaurants
您可以在borough
和cuisine
字段上添加部分索引,仅选择索引rating.grade
字段为的文档A
:
然后,对restaurants
集合的以下查询使用部分索引返回Bronx中rating.grade
等于的餐厅A
:
但是,以下查询不能使用部分索引,因为查询表达式不包含该rating.grade
字段:
具有唯一约束的部分索引
部分索引仅索引集合中符合指定过滤器表达式的文档。如果同时指定 partialFilterExpression
和约束,则唯一约束仅适用于满足过滤器表达式的文档。如果文档不符合过滤条件,则具有唯一约束的部分索引不会阻止插入不符合唯一约束的文档。
例如,集合users包含以下文档:
下面的操作创建了一个索引,该索引在**“username”**字段上指定了一个unique constraint和一个部分过滤表达式age: {$gte: 21}
。
由于指定用户名的文档已经存在,且**“age”字段大于21**,因此索引防止插入以下文档:
但是,允许使用重复用户名的以下文档,因为唯一约束只适用于**“age”大于或等于21**的文档。
最后更新于