如何加快聚合中的$ group阶段

时间:2017-08-04 15:59:12

标签: mongodb mongodb-query aggregation-framework

我的查询执行得太慢了:

db.pmusers.aggregate(
    {
        $unwind: '$preferableUsersIds'
    },
    {
        $addFields: {count:1}
    },
    {
        $group:{_id: '$preferableUsersIds', number:{$sum:"$count"}}
    },
    {
        $sort:{number:-1}
    },
    {
        $limit:1
    }
)

我注意到$group这个问题的原因 你能建议加快速度吗?

P.S。

根据我读过谷歌的信息 - 添加索引无济于事

我可以说我尝试了db.pmusers.createIndex({preferableUsersIds:1});

db.pmusers.createIndex({_id:1, preferableUsersIds:1});

但这没有帮助

P.S.2

解释

 db.pmusers.aggregate( [{$unwind: '$preferableUsersIds' }, { $addFields: { cmp_value: {$cmp:['$id', '$preferableUsersIds']} } }, { $match: { cmp_value: {$eq: 0} } }], {explain:true} )
{
        "stages" : [
                {
                        "$cursor" : {
                                "query" : {

                                },
                                "queryPlanner" : {
                                        "plannerVersion" : 1,
                                        "namespace" : "mydb.pmusers",
                                        "indexFilterSet" : false,
                                        "parsedQuery" : {

                                        },
                                        "winningPlan" : {
                                                "stage" : "COLLSCAN",
                                                "direction" : "forward"
                                        },
                                        "rejectedPlans" : [ ]
                                }
                        }
                },
                {
                        "$unwind" : {
                                "path" : "$preferableUsersIds"
                        }
                },
                {
                        "$addFields" : {
                                "cmp_value" : {
                                        "$cmp" : [
                                                "$id",
                                                "$preferableUsersIds"
                                        ]
                                }
                        }
                },
                {
                        "$match" : {
                                "cmp_value" : {
                                        "$eq" : 0
                                }
                        }
                }
        ],
        "ok" : 1
}

1 个答案:

答案 0 :(得分:1)

正如您所提到的,$group无法使用索引,但您只需投影preferableUsersIds并删除$addFields阶段就可以做一些事情来提高管道效率:

db.pmusers.aggregate([
    {
        $project: {_id: 0, 'preferableUsersIds': 1}
    },
    {
        $unwind: '$preferableUsersIds'
    },
    {
        $group:{_id: '$preferableUsersIds', number:{$sum: 1}}
    },
    {
        $sort:{number:-1}
    },
    {
        $limit:1
    }
])

不幸的是,仍然无法使用索引,因为只有$match$sort在管道开头使用时才能这样做。