Mongodb:聚合排序限制查询的索引?

Posted

技术标签:

【中文标题】Mongodb:聚合排序限制查询的索引?【英文标题】:Mongodb: Indexing for Aggregate sort limit query? 【发布时间】:2016-01-20 11:47:26 【问题描述】:

我正在从 mysql 迁移到 mongodb。昨天开始学习mongodb。

我有一个很大的 mysql 表(超过 400 万行,每个包含 300 多个字段),我将把它移到 mongodb。

假设 products 表有以下字段 -

_id、类别和 300 多个其他字段。

要查找 产品中的前 5 个类别及其数量,我有以下 mysql 查询

Select category, count(_id) as N from products group by category order by N DESC limit 5;

我在category 字段上有一个索引,这个查询在 mysql 中大约需要 4.4 秒

现在,我已成功将此表移至 mongodb,这是我查找前 5 个类别及其计数的相应查询。

db.products.aggregate([$group : _id:"$category", N:$sum:1,$sort:N: -1,$limit:5]);

我再次在 category 上有一个索引,但查询似乎没有使用它(解释:true 是这样说的),而且这个查询也需要大约 13.5 秒

阅读了有关 mongodb 聚合管道优化的更多信息后,我发现我们需要在聚合之前使用排序才能使索引正常工作,但我正在对聚合中的派生字段进行排序,因此无法将其放在聚合函数之前。

如何在 mongodb 中优化此类查询?

================================================ =========================== 解释的输出

db.products.aggregate([$group : _id:"$category",N:$sum:1,$sort:N: -1,$limit:5],  explain: true );

        "waitedMS" : NumberLong(0),
        "stages" : [
                
                        "$cursor" : 
                                "query" : 

                            ,
                            "fields" : 
                                    "category" : 1,
                                    "_id" : 0
                            ,
                            "queryPlanner" : 
                                    "plannerVersion" : 1,
                                    "namespace" : "mydb.products",
                                    "indexFilterSet" : false,
                                    "parsedQuery" : 
                                            "$and" : [ ]
                                    ,
                                    "winningPlan" : 
                                            "stage" : "COLLSCAN",
                                            "filter" : 
                                                    "$and" : [ ]
                                            ,
                                            "direction" : "forward"
                                    ,
                                    "rejectedPlans" : [ ]
                            
                    
            ,
            
                    "$group" : 
                            "_id" : "$category",
                            "N" : 
                                    "$sum" : 
                                            "$const" : 1
                                    
                            
                    
            ,
            
                    "$sort" : 
                            "sortKey" : 
                                    "N" : -1
                            ,
                            "limit" : NumberLong(5)
                    
            
    ],
    "ok" : 1

【问题讨论】:

你能发布explain查询的输出吗 增加了解释查询的输出。 【参考方案1】:

在我们的用例中,聚合框架在提高性能方面目前存在一些限制,但是,您应该能够通过首先对类别进行排序来加快查询速度。这将强制查询使用您添加的索引,并应加快管道第二部分中的组查询:

 db.products.aggregate([ 
     "$sort" :  "category" : 1 ,
    $group : _id:"$category",N:$sum:1,
    $sort:N: -1,$limit:5]);

【讨论】:

是的,这已将执行时间降低到 7.9 秒左右,并且正在使用类别索引。谢谢。看起来 mysql 更适合这个用例。

以上是关于Mongodb:聚合排序限制查询的索引?的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB索引

MongoDB查询区分、排序、限制和偏移

005.MongoDB索引及聚合

mongoDB应用篇-mongo聚合查询

mongodb Aggregation聚合操作之$sort

你如何告诉 Mongo 在限制结果之前对集合进行排序?