天天看点

Yii2 MongoDB多字段分组汇总统计

/* 1 */
{
    "_id" : ObjectId("5b3dbe4760e59d22d06ec4ae"),
    "user_id" : ObjectId("5b0657c92bb7b0325d45f566"),
    "login_date" : "2018-05-24",
    "create_time" : ISODate("2018-05-24T06:12:25.188Z")
}

/* 2 */
{
    "_id" : ObjectId("5b3dd35fe1382307183afa2c"),
    "user_id" : ObjectId("5b3dd31fe13823071a706aec"),
    "create_time" : ISODate("2018-07-05T08:14:23.725Z"),
    "login_date" : "2018-07-05"
}

/* 3 */
{
    "_id" : ObjectId("5b3dd3a4e1382307144a7fcc"),
    "user_id" : ObjectId("5b3dd31fe13823071a706aec"),
    "create_time" : ISODate("2018-07-05T08:15:32.714Z"),
    "login_date" : "2018-07-05"
}

/* 4 */
{
    "_id" : ObjectId("5b42c3249248b302b75fc262"),
    "user_id" : ObjectId("5b0657d42bb7b02e7d7d702e"),
    "create_time" : ISODate("2018-07-07T02:06:28.699Z"),
    "login_date" : "2018-07-07"
}
           

实例场景:统计时间范围内的登录用户总数,同一天同用户多次登录只算一次登录。

分析:首先,要对日期进行分组;然后,对同一天内的相同用户进行去重操作;由于,在数据量大的时候无法使用distinct函数。因此,需要使用aggregate。

实例代码:

$data = UserLoginLog::getCollection()->aggregate([
            [
                '$match'=>[
                    'create_time' => [ // 日期搜索条件
                        '$gte'=>$startDate,
                        '$lt'=>$endDate
                    ]
                ]
            ],[
                '$group'=>[
                    '_id'=>['login_date'=>'$login_date', 'user_id'=>'$user_id'], //通过user_id分组去重
                    'count'=>[
                        '$sum'=>1
                    ]
                ]
            ],[
                '$group'=>[
                    '_id'=>null, //统计总数据量
                    'count'=>[
                        '$sum'=>1
                    ]
                ]
            ],[
                '$project'=>[
                    '_id'=>0, //不输出_id字段
                    'count'=>1
                ]
            ]
        ]);