[MongoDB]时间戳或数值分组聚合统计

样本数据如下:

[
    {
        "data": {
            "fee": 0
        },
        "create_time": 1654484486
    },
    {
        "data": {
            "fee": 2000
        },
        "create_time": 1654484493
    },
    {
        "data": {
            "fee": 2000
        },
        "create_time": 1654484495
    },
    {
        "data": {
            "fee": 0
        },
        "create_time": 1654484497
    },
    {
        "data": {
            "fee": 600
        },
        "create_time": 1654484499
    },
    {
        "data": {
            "fee": 2000
        },
        "create_time": 1654499821
    },
    {
        "data": {
            "fee": 4000
        },
        "create_time": 1654499827
    },
    {
        "data": {
            "fee": 1200
        },
        "create_time": 1654499829
    }
]

根据此样本数据,需要统计出字段create_time每一个小时内的data.fee的值合计,写法如下:

db.getCollection('test集合名').aggregate({
    "$match": {
        "create_time": {
            "$gte": 1654484481, /* 开始范围时间戳(10位) */
            "$lte": 1654499830 /* 结束范围时间戳(10位) */
        }
    }
},
{
    "$group": {
        "_id": {
            "$subtract": [
                {
                    "$subtract": [
                        "$create_time",
                        0 /* 如果数值基值不为0则需要调整 */
                    ]
                },
                {
                    "$mod": [
                        {
                            "$subtract": [
                                "$create_time",
                                0
                            ]
                        },
                        60 * 60 /* 递增方式 60*60 10位时间戳的1小时 */
                    ]
                }
            ]
        },
        "total": {
            "$sum": "$data.fee" /* 需要统计的值 */
        }
    }
}
)

最后查询的结果如下:

{
    "_id" : 1654484400.0,
    "total" : 4600
},
{
    "_id" : 1654498800.0,
    "total" : 7200
}

返回结果的意义为:1654484400 - 1654488000的fee统计合计为:4600,以此往下。

根据需求,编写出的doctrine mongo odm的代码:

$builder->match()->field('create_time')->range(1654484481, 1654499830);
$builder->group()
    ->field('_id')
    ->subtract('$create_time', $builder->expr()->mod('$create_time', 60*60))
    ->field('total')
    ->sum('$data.fee');