【问题标题】:Why Multi Query in MongoDB does not return data in sorted order?为什么 MongoDB 中的多查询不按排序顺序返回数据?
【发布时间】:2020-10-03 22:02:28
【问题描述】:

它来自 MongoDB:权威指南。首先,我们通过{"age": 1, "username": 1} 索引users 集合。据说,age字段严格按照升序排列,每个年龄内username的字段也是升序排列。

查询 1:db.user.find({"age": 21}).sort({"username": -1})
在查询 1 中,MongoDB 从 {"age": 21} 的最后一个匹配项开始,并以相反的顺序遍历索引。这样,我们得到username 的降序排列。这意味着,MongoDB 线性选择文档

问题 2:db.users.find({"age": {"$gte": 21, "$lte": 30}}).sort({"username" : 1})
但是现在,在查询 2 中,它表示索引没有按排序顺序返回 usernames,因此 MongoDB 必须在返回之前对内存中的结果进行排序。因此,为了以有序的方式获得usernames,我们必须以相反的顺序设置索引,即{"username": 1, "age": 1}。现在在这里,如果 MongoDB 线性选择 ages,那么 usernames 必须按升序排列。但这里不是这样,为什么会这样?

【问题讨论】:

    标签: database mongodb


    【解决方案1】:

    我同意你问题的第一部分,索引{"age": 1, "username": 1} 应该由首先按年龄(升序)拆分,然后按用户名(也按升序)拆分的 B 树实现。

    我同意你在第一个问题上所说的:

    db.user.find({"age": 21}).sort({"username": -1})
    

    限制为单个age 值后,除此之外,所有拆分都应仅在username 上进行,并且应按升序排序。这意味着 Mongo 可以直接按原始顺序读取索引条目,以满足查询管道的排序部分。话虽如此,我认为 Mongo 没有理由不能在任何一个方向上使用索引,无论是向前还是向后,所以我也希望以下查询具有相同的执行计划:

    db.user.find({"age": 21}).sort({"username": 1})
    

    关于您的第二个查询:

    db.users.find({"age": {"$gte": 21, "$lte": 30}}).sort({"username" : 1})
    

    这里的问题是索引不能同时覆盖查询管道的过滤和排序部分。它确实涵盖了age 上的过滤器,但它仅限制在 B 树内的age 值的范围。在该年龄范围内,不能假定用户名值已排序。因此,Mongo 将不得不进行内存排序。

    但要记住第二个查询的关键是内存排序并不像您想象的那么昂贵。 Mongo 只需对 索引条目 进行排序,而不是对实际的 BSON 文档进行排序。通常,Mongo 可能会使用运行快速的合并排序等分而治之的算法来实现排序。对索引条目进行排序后,将需要查找原始用户集合中每个索引条目的字段。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-04-22
      • 1970-01-01
      • 2022-06-11
      • 1970-01-01
      • 1970-01-01
      • 2022-12-16
      • 2023-04-05
      • 1970-01-01
      相关资源
      最近更新 更多