欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【MongoDB】多键索引的边界处理(一)

程序员文章站 2024-03-16 22:00:22
...

本文将探讨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: 等值查询

    ..............................

【MongoDB】多键索引的边界处理(一)

一、多键索引的相交边界

边界相交是指多个边界的逻辑与(即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不保证选择这两个界限中的哪一个

二、多键索引的复合边界

见下篇文章。