草庐IT

mongodb - Mongo $group 太慢了

coder 2023-10-26 原文

我有一个包含大约 168,200,000 个文档的 mongo 数据库集合。我正在尝试使用 $group 获取某个字段的平均值,并且我在管道中的 $group 之前使用 $match 来使用 client.city 上的索引。但是查询大约需要 5 分钟才能运行,这非常慢。

这是我尝试过的:

db.ar12.aggregate(
    {$match:{'client.city':'New York'}},
    {'$group':{'_id':'client.city', 'avg':{'$avg':'$length'}}}
)

db.ar12.aggregate(
    {$match:{'client.city':'New York'}},
    {'$group':{'_id':null, 'avg':{'$avg':'$length'}}}
)

db.ar12.aggregate(
    {$match:{'client.city':'New York'}}, 
    {$project: {'length':1}},
    {'$group':{'_id':null, 'avg':{'$avg':'$length'}}}
)

所有 3 个查询花费的时间大致相同,client.city = to New York 的文档数量为 1,231,672,find({'client.city':'New York').count() 需要一秒钟才能运行

> db.version()
  3.2.0

编辑

这是解释结果...至于添加带长度的复合索引的评论,这会有帮助吗,虽然我不是按长度搜索我想要所有长度...

{
"waitedMS" : NumberLong(0),
"stages" : [
    {
        "$cursor" : {
            "query" : {
                "client.city" : "New York"
            },
            "fields" : {
                "length" : 1,
                "_id" : 1
            },
            "queryPlanner" : {
                "plannerVersion" : 1,
                "namespace" : "clients.ar12",
                "indexFilterSet" : false,
                "parsedQuery" : {
                    "client.city" : {
                        "$eq" : "New York"
                    }
                },
                "winningPlan" : {
                    "stage" : "FETCH",
                    "inputStage" : {
                        "stage" : "IXSCAN",
                        "keyPattern" : {
                            "client.city" : 1
                        },
                        "indexName" : "client.city_1",
                        "isMultiKey" : false,
                        "isUnique" : false,
                        "isSparse" : false,
                        "isPartial" : false,
                        "indexVersion" : 1,
                        "direction" : "forward",
                        "indexBounds" : {
                            "client.city" : [
                                "[\"New York\", \"New York\"]"
                            ]
                        }
                    }
                },
                "rejectedPlans" : [ ]
            }
        }
    },
    {
        "$project" : {
            "length" : true
        }
    },
    {
        "$group" : {
            "_id" : {
                "$const" : null
            },
            "total" : {
                "$avg" : "$length"
            }
        }
    }
],
"ok" : 1
}

编辑 2

我加了client.city和length的复合索引,还是不行,速度还是太慢,我试了这2个查询:

db.ar12.aggregate(
    {$match: {'client.city':'New York'}}, 
    {$project: {'client.city':1, 'length':1}},
    {'$group':{'_id':'$client.city', 'avg':{'$avg':'$length'}}}
)

上面的查询没有使用复合索引,所以我尝试强制使用它,但仍然没有任何改变:

db.ar12.aggregate(
    {$match: { $and : [{'client.city':'New York'}, {'length':{'$gt':0}}]}}, 
    {$project: {'client.city':1, 'length':1}},
    {'$group':{'_id':'$client.city', 'avg':{'$avg':'$length'}}}
)

下面是最后一个查询的解释:

{
"waitedMS" : NumberLong(0),
"stages" : [
    {
        "$cursor" : {
            "query" : {
                "$and" : [
                    {
                        "client.city" : "New York"
                    },
                    {
                        "length" : {
                            "$gt" : 0
                        }
                    }
                ]
            },
            "fields" : {
                "client.city" : 1,
                "length" : 1,
                "_id" : 1
            },
            "queryPlanner" : {
                "plannerVersion" : 1,
                "namespace" : "clients.ar12",
                "indexFilterSet" : false,
                "parsedQuery" : {
                    "$and" : [
                        {
                            "client.city" : {
                                "$eq" : "New York"
                            }
                        },
                        {
                            "length" : {
                                "$gt" : 0
                            }
                        }
                    ]
                },
                "winningPlan" : {
                    "stage" : "CACHED_PLAN",
                    "inputStage" : {
                        "stage" : "FETCH",
                        "inputStage" : {
                            "stage" : "IXSCAN",
                            "keyPattern" : {
                                "client.city" : 1,
                                "length" : 1
                            },
                            "indexName" : "client.city_1_length_1",
                            "isMultiKey" : false,
                            "isUnique" : false,
                            "isSparse" : false,
                            "isPartial" : false,
                            "indexVersion" : 1,
                            "direction" : "forward",
                            "indexBounds" : {
                                "client.city" : [
                                    "[\"New York\", \"New York\"]"
                                ],
                                "length" : [
                                    "(0.0, inf.0]"
                                ]
                            }
                        }
                    }
                },
                "rejectedPlans" : [ ]
            }
        }
    },
    {
        "$project" : {
            "client" : {
                "city" : true
            },
            "length" : true
        }
    },
    {
        "$group" : {
            "_id" : "$client.city",
            "avg" : {
                "$avg" : "$length"
            }
        }
    }
],
"ok" : 1
}

最佳答案

我找到了解决方法,长度从 1 到 70。所以我在 python 中从 1 迭代到 70,找到每个城市的每个长度的计数,

db.ar12.find({'client.city':'New York', 'length':i}).count()

速度非常快,然后用python计算平均值,运行大约需要2秒。

这不是最好的解决方案,因为我还有其他查询要运行,我不知道我是否可以找到解决所有这些问题的方法...

关于mongodb - Mongo $group 太慢了,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34797416/

有关mongodb - Mongo $group 太慢了的更多相关文章

  1. ruby-on-rails - rails group by 和 order by column - 2

    在我的Controller中,我得到了按类别分组的所有Extras:defindex@categories=Extra.all.group_by(&:category)end结果类似于哈希数组:{#=>[#,#=>[#,#]}我想按类别“排序”列而不是id排序,它应该如下所示:{#=>[#,#=>[#,#]}当我尝试时:defindex@categories=Extra.all.group_by(&:category).sort_by{|s|s[:sort]}end我得到“没有将符号隐式转换为整数”。那是因为我在“sort_by”中使用了一个符号吗? 最佳答

  2. ruby - 如何将 Thor::Group 注册为带参数的子命令 - 2

    这道题开始于here.但随着我对雷神的了解越来越多,情况发生了很大变化。我正在尝试创建一个带参数的Thor::Group子命令。奇怪的是,如果没有参数,它就可以工作。我可以使用Thor::Group作为子命令吗?这在我输入时有效:foocounterfoo/bin/foomoduleFooclassCLI但是当我输入时这不起作用:foocounter5moduleFooclassCLI','Countupfromtheinput.')endclassCounter:numeric,:desc=>"Thenumbertostartcounting"desc"Prints2numbersb

  3. ruby - 从 Ruby 中的排序数组创建嵌套哈希——递归 group_by - 2

    我有一个对象数组,这些对象已根据这些对象的几个属性进行了排序。按照优先顺序,这些属性是foo、bar和baz。这意味着对象首先按foo排序;然后具有相同foo值的子序列按bar排序;然后具有相同foo和bar值的那些按baz排序。我想将其转换为反射(reflect)该分组的嵌套哈希。基本上我正在寻找递归Enumerable#group_by。键是foo、bar和baz的值;这些值将是对象的子哈希或数组。这是一个例子:[obj1,obj2,...objn].group_by_recursive(:foo,:bar,:baz)#=>{foo_val_1=>{bar_val_1=>{baz_

  4. ruby-on-rails - Rails group_by 是否已弃用? - 2

    我有一个要分组的数组,“group_by”函数似乎适合我的情况。http://apidock.com/rails/Enumerable/group_by我在Rails3.2.13中使用它。grouped_array=my_array.group_by(&:my_function)#Assumerun'my_function'haveresult1onelement1,element3andresult2onelement2,element4,then:#grouped_array={#result1=>[element1,element3],#result2=>[element2,el

  5. ruby-on-rails - 如何使用 grouped_collection_select 显示多选? - 2

    我正在使用以下代码来显示类别的TreeView选择框:grouped_collection_select(:categories,:category_id,Category.top_level,:children,:name,:id,:name,:include_blank=>true)如何更改它以允许多选?此外,是否可以让它显示复选框而不是选择框? 最佳答案 尝试grouped_collection_select(:categories,:category_id,Category.top_level,:children,:name

  6. ruby-on-rails - ruby group_by 对象? - 2

    我有一个数组或不同的对象,我想按对象分组。例如=>[#,#,#,#]all.size=>4我试过了all.group_by(Object)但这没有用...关于如何对一个数组中的对象进行分组有什么想法吗? 最佳答案 你想做这样的事情吗?all.group_by(&:class)它将数组中的对象按类名分组编辑评论all.group_by(&:class).eachdo|key,group|group.each{|item|putsitem}endKey是分组元素,obj是键的集合,因此这将遍历分组中的每个组并列出该组中的对象您也可以很容

  7. ruby - 为什么需要 mongo 给我 LoadError : no such file to load -- openssl - 2

    我正在使用UbuntuServer10,Ruby1.9.2当我尝试要求'mongo'时它给我这个错误:irb(main):001:0>require'mongo'LoadError:nosuchfiletoload--opensslfrom/usr/local/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in`require'from/usr/local/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in`require'from/usr/local/lib

  8. ruby-on-rails - Rails 3.1 与 PostgreSQL : GROUP BY must be used in an aggregate function - 2

    我正在尝试加载按user_id分组并按created_at排序的最新10个艺术。这适用于SqlLite和MySQL,但在我的新PostgreSQL数据库上出错。Art.all(:order=>"created_atdesc",:limit=>10,:group=>"user_id")ActiveRecord错误:ArtLoad(18.4ms)SELECT"arts".*FROM"arts"GROUPBYuser_idORDERBYcreated_atdescLIMIT10ActiveRecord::StatementInvalid:PGError:ERROR:column"arts.i

  9. ruby-on-rails - 在一个 Rails 应用程序中使用 PostgreSQL 的 MongoDB - 2

    我可以在一个Rails应用程序中同时使用MongoDB和PostgreSQL吗?具体来说,我最终会想要使用像MongoHQ这样的东西。到目前为止,我未能在实验中进行这项工作。令我担心的是,MongoDB文档特别指出我必须禁用ActiveRecord。任何建议将不胜感激。 最佳答案 您无需禁用ActiveRecord即可使用MongoDB。查看Mongoid只需将gem加上任何模型与您现有的任何ActiveRecord模型一起添加。您应该注意到MongoHQ只是MongoDB的托管服务,可以与任何对象文档映射器(ODM)一起使用。更多

  10. ruby-on-rails - rails - 使用 Group_by 时 - 如何获取索引? - 2

    我有以下内容:sets=DataSet.all.group_by{|data|[data.project_id,"-",data.thread_id].join("")}:LastPost问题是我需要一个索引。所以我更新了上面的内容::LastPost然后中断,出现错误:undefinedmethod`last'for0:Fixnum想法?谢谢 最佳答案 您观察到的问题是因为参数分配给block的方式。在您的第二个示例中,您将观察到range包含一个包含单个range和匹配的datas的数组,datas变量包含索引,i始终为nil。

随机推荐