【问题标题】:Sorting on Multiple fields mongo DB对多个字段排序 mongoDB
【发布时间】:2012-09-20 16:47:00
【问题描述】:

我在 mongo 中有一个查询,因此我想优先考虑第一个字段,然后是第二个字段。

假设我必须这样查询

db.col.find({category: A}).sort({updated: -1, rating: -1}).limit(10).explain()

所以我创建了以下索引

db.col.ensureIndex({category: 1, rating: -1, updated: -1})

它可以根据需要扫描尽可能多的对象,即10

但现在我需要查询

db.col.find({category: { $ne: A}}).sort({updated: -1, rating: -1}).limit(10)

所以我创建了以下索引:

 db.col.ensureIndex({rating: -1, updated: -1})

但这会导致扫描整个文档以及创建时

 db.col.ensureIndex({ updated: -1 ,rating: -1})

它扫描的文档数量更少:

我只想问清楚对多个字段进行排序以及这样做时要保留的顺序是什么。通过阅读 MongoDB 文档,很明显我们需要对其执行排序的字段应该是最后一个字段。这就是我在上面的$ne 查询中假设的情况。我做错什么了吗?

【问题讨论】:

    标签: mongodb nosql


    【解决方案1】:

    MongoDB query optimizer 通过尝试不同的计划来确定哪种方法最适合给定查询。然后缓存该查询模式的获胜计划以供接下来的约 1,000 个查询或直到您执行explain()

    要了解考虑了哪些查询计划,您应该使用explain(1),例如:

    db.col.find({category:'A'}).sort({updated: -1}).explain(1)
    

    allPlans 详细信息将显示所有已比较的计划。

    如果您运行的查询不是很有选择性(例如,如果许多记录与您的 {category: { $ne:'A'}} 条件匹配),MongoDB 使用 BasicCursor(表扫描)查找结果可能比匹配索引。

    查询中的字段顺序通常不会对索引选择产生影响(范围查询有一些例外)。 sort 中的字段顺序确实会影响索引选择。如果您的sort() 条件与索引顺序不匹配,则必须在使用索引后重新排序结果数据(如果发生这种情况,您应该在解释输出中看到scanAndOrder:true)。

    另外值得注意的是,MongoDB 只会使用one index per query$ors 除外)。

    因此,如果您尝试优化查询:

    db.col.find({category:'A'}).sort({updated: -1, rating: -1})
    

    您需要在索引中包含所有三个字段:

    db.col.ensureIndex({category: 1, updated: -1, rating: -1})
    

    仅供参考,如果您想强制特定查询使用索引(通常不需要或不推荐),您可以尝试hint() 选项。

    【讨论】:

    • 这如何回答这个问题?您仍然无法确保按“评级 desc,更新的 desc”而不是“更新的 desc,评级 desc”的顺序获得排序
    • @jobermark 在原始问题中,查询条件为category,复合排序顺序为{updated: -1, rating: -1}。索引中键的顺序(和方向)很重要;建议的索引将无法有效地支持在content 上按{rating: -1, updated: -1} 排序的搜索。如果您在驱动程序中操作复合排序值,请使用有序哈希/字典以确保保留排序。有关详细信息,请参阅 MongoDB 文档中的 Sort on Multiple Fields
    【解决方案2】:

    确实如此,但由于您是在复合索引上排序,因此这里有两层排序。

    正如您注意到的,当索引的第一个字段与排序的第一个字段匹配时,它起作用并且索引被看到。但是,当以相反的方式工作时不会。

    因此,根据您自己的观察,需要保留的顺序是从第一个到最后一个字段的查询顺序。 mongo 分析器有时可以在字段中移动以匹配索引,但通常它只会尝试匹配第一个字段,如果不能,它将跳过它。

    【讨论】:

      【解决方案3】:

      试试这个代码,它将首先根据名称对数据进行排序,然后将“名称”保留在密钥持有者中,它将对“过滤器”进行排序

       var cursor = db.collection('vc').find({   "name" :   { $in: [ /cpu/, /memo/ ]   }     }, { _id: 0, }).sort( { "name":1  ,  "filter": 1 } );
      

      【讨论】:

        【解决方案4】:
        Sort and Index Use¶
        
        MongoDB can obtain the results of a sort operation from an index which includes the sort fields. MongoDB may use multiple indexes to support a sort operation if the sort uses the same indexes as the query predicate. ... Sort operations that use an index often have better performance than blocking sorts.
        
        db.restaurants.find().sort( { "borough": 1, "_id": 1 } )
        

        更多信息: https://docs.mongodb.com/manual/reference/method/cursor.sort/

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-06-03
          • 2019-03-30
          • 2016-12-23
          • 1970-01-01
          • 1970-01-01
          • 2021-11-03
          • 2020-03-04
          • 1970-01-01
          相关资源
          最近更新 更多