【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不保证选择这两个界限中的哪一个

二、多键索引的复合边界

见下篇文章 《多键索引的边界处理(二)》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值