• mongodb 中的Multikey Index Bounds解释$elemMatch


    首先说一下 $elemMatch的用法:

    { _id: 1, results: [ 82, 85, 88 ] }

    { _id: 2, results: [ 75, 88, 89 ] }

    $elemMatch是匹配document 中数组中至少有一个元素满足$elemMatch中的所有条件,例如:

    db.scores.find(
       { results: { $elemMatch: { $gte: 80, $lt: 85 } } }
    )

    查询结果为:

    { "_id" : 1, "results" : [ 82, 85, 88 ] }

    结下来解释一下(Multikey Index Bounds):
    在一个查询期间,索引的扫描范围定义了部分索引为了搜索,当多个(条件)predicates 超过一个索引存在时:mongodb 将试图去合并这些(条件)predicates的边界,要么通过求交集的方法合并
    要么通过组合的方法,为了去产生一个比较小的扫描范围。
    给定一个索引数组字段,考虑到在一个查询中,在一个数组中指定了多个(条件)predicates并且可以使用 Multikey Index。
    if $elemMatch 中有多个(条件)predicates ,mongodb会合并 Multikey Index的边界。因此,会有$elemMatch是匹配document 中数组中至少有一个元素满足$elemMatch中的所有条件。

    继续上面的例子,逐个条件边界的范围:
    大于等于80($gte:80)的边界为[80,inf];
    小于85
    ($lt:85)的边界为[-inf,85]。
    由于使用了$
    elemMatch组织多个条件查询,mongodb查询的边界为results:[[80,85)]。

    我们在来看一下(Compound Bounds for Multikey Index)

    由于上面的查询条件可以求交集,但是,假如还有一种情况,有两个数组:

    _id1results828588 ],scores:[66,77,88] }

    _id2results758889 ] ,scores:[77,44,22]}

    查询条件为:

    db.scores.find(
       { results: { $gte: 85 },scores:{$lt:60}}
    )
    他们是没有交集的,在这种情况下,索引的边界是怎么样的呢?就继续看
    Compound Bounds for Multikey Index
    把同一个数组中的不同索引键的边界混合在一起的条件如下:
      这些索引的keys必须有相同的字段路径,但是不包括字段的names
      这个查询必须在指定的字段路径的这个特定的字段上面使用$elemMatch
    还是看例子:
    {
      _id: 1,
      item: "ABC",
      ratings: [ { score: 2, by: "mn" }, { score: 9, by: "anon" } ]
    }
    {
      _id: 2,
      item: "XYZ",
      ratings: [ { score: 5, by: "anon" }, { score: 7, by: "wv" } ]
    }

    创建索引:
    db.survey2.createIndex( { "ratings.score": 1, "ratings.by": 1 } )

    查询语句:
    db.survey2.find( { ratings: { $elemMatch: { score: { $lte: 5 }, by: "anon" } } } )
    逐个索引分析:
    score {$lte:5}的边界是:[-inf,5],
    by {by:"anon"}的边界是:["anon":"anon"]
    mongodb 索引混合的结果为:
    { "ratings.score" : [ [ -Infinity, 5 ] ], "ratings.by" : [ [ "anon", "anon" ] ] }

    再看一个例子:
    {
      _id: 1,
      item: "ABC",
      ratings: [
        { score: { q1: 2, q2: 5 }, certainty: { q1: 2, q2: 3 } },
        { score: { q1: 8, q2: 4 }, certainty: { q1: 10, q2: 10 } }
      ]
    }
    {
      _id: 2,
      item: "XYZ",
      ratings: [
        { score: { q1: 7, q2: 8 }, certainty: { q1: 5, q2: 5 } },
        { score: { q1: 9, q2: 5 }, certainty: { q1: 7, q2: 7 } }
      ]
    }
    创建的索引为:
    db.survey4.createIndex( {
       "ratings.score.q1": 1,
       "ratings.score.q2": 1,
       "ratings.certainty.q1": 1,
       "ratings.certainty.q2": 1
    } )
    查询的语句为:
    db.survey4.find(
      {
        "ratings.score": { $elemMatch: { q1: 5, q2: 5 } },
        "ratings.certainty": { $elemMatch: { q1: 7, q2: 7 } },
      } 
    但是,当$elemMatch不能连接
    "ratings.score"和"ratings.certainty",mongodb 不能混合它们两个的边界,然而,mongodb 强制领导索引字段"ratings.score.q1" 和 "ratings.score.q2"的边界混合。
    边界的混合结果如下:
    {
      "ratings.score.q1" : [ [ 5, 5 ] ],
      "ratings.score.q2" : [ [ 5, 5 ] ],
      "ratings.certainty.q1" : [ [ MinKey, MaxKey ] ],
      "ratings.certainty.q2" : [ [ MinKey, MaxKey ] ]
    }


     



    
    





  • 相关阅读:
    python面向对象--类的刨析
    python装饰器中高级用法(函数加参)
    运用python中装饰器方法来解决工作中为原有代码添加功能问题
    python学习之路---基础概念扩展:变量,表达式,算法,语句,函数,模块,字符串
    理解cpu过高的逻辑思维与分析方法
    mysql 二进制安装
    K8s高可用集群部署(四)
    K8S集群管理+docker私有仓库harbor搭建(三)
    Python之内置函数的一些使用
    Python之处理svg文件中的style属性
  • 原文地址:https://www.cnblogs.com/Kellana/p/5972808.html
Copyright © 2020-2023  润新知