【MongoDB】多键索引的边界处理(一)
本文将探讨MongoDB在查询时候,对于多键索引边界(Multikey Index Bounds)如何处理。比如db.survey.find( { ratings : { $elemMatch: { $gte: 3, $lte: 6 } } } ),查询范围是多少呢?
本章内容:
- 多键索引的相交边界
- 多键索引的复合边界
索引扫描的范围定义了在查询期间要检索的部分索引。当作一个索引有多个谓词(predicates)作用于它时,MongoDB将尝试通过相交或复合来组合这些谓词的边界,以产生具有较小扫描范围。
看看sql server关于谓词(predicates)的解释:
什么是谓词呢?谓词是取值为 TRUE、FALSE 或 UNKNOWN 的表达式。 谓词用于WHERE子句和HAVING子句的搜索条件中,还用于FROM子句的联接条件以及需要布尔值的其他构造中。官方的解释为:A predicate is an expression that evaluates to True or False 。在WHERE条里面的常见的谓词形式有:
1: LIKE模糊查询。
2: BETWEEN范围查询
3: IS NULL、IS NOT NULL判断
4: IN - OR
5: EXIST
6: 等值查询
..............................
一、多键索引的相交边界
边界相交是指多个边界的逻辑与(即AND)操作。例如,给定两个边界[[3,Infinity]]和[[-Infinity,6]],边界的交点将得出[[3,6]]。
注释
infinity 无限; 无穷。表示无穷的符号是(∞),为了便于理解,后文用符号∞来代替infinity。
给定一个数组字段的索引,请考虑一个查询,该查询在数组上指定多个谓词并且可以使用多键索引。如果$elemMatch加入谓词,MongoDB让多键索引边界相交。
例如,一个叫survey的集合包含带有字段item和数组字段ratings的文档:
{ _id: 1, item: "ABC", ratings: [ 2, 9 ] }
{ _id: 2, item: "XYZ", ratings: [ 4, 3 ] }
在ratings数组上创建一个多键索引:
db.survey.createIndex( { ratings: 1 } )
以下查询使用$ elemMatch要求数组中至少包含一个元素要同时匹配两个条件:
db.survey.find( { ratings : { $elemMatch: { $gte: 3, $lte: 6 } } } )
将谓词分开:
- 谓词 大于或等于3(即$gte:3)的边界为[[3,∞]];
- 谓词 小于或等于6(即$lte:6)的边界是[[- ∞,6]]。
由于查询语句使用$elemMatch连接这些谓词,因此MongoDB可以将边界逻辑与运算:
ratings: [ [ 3, 6 ] ]
如果查询未使用$ elemMatch联接数组字段上的条件,则MongoDB无法将多键索引界限进行与运算。考虑以下查询:
db.survey.find( { ratings : { $gte: 3, $lte: 6 } } )
该查询在ratings数组中搜索至少一个大于或等于3的元素以及至少一个小于或等于6的元素。由于单个元素不需要同时满足两个条件,因此MongoDB不会将界限与运算,并且使用其中一个 [
[
3,
∞]
] 或[
[
-∞,
6
]
]。 MongoDB不保证选择这两个界限中的哪一个。
二、多键索引的复合边界
见下篇文章。
上一篇: 软件调用时间数量级 博客分类: java
下一篇: iptables 来进行端口转发