You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Doctrine ODM MongoDB聚合框架实现按类型、年月嵌套分组并聚合计数的问题

Doctrine ODM MongoDB聚合框架实现按类型、年月嵌套分组并聚合计数的问题

我明白你现在遇到的问题啦——当前的聚合逻辑只是把每个文档的年月数据直接推送到数组里,没有对同一年月的条目做合并统计。要实现先按类型分组,再在每个类型下按年月聚合计数的效果,我们需要分两次使用$group阶段来完成:

正确的聚合步骤

  1. 第一次分组:按类型+年月组合统计
    先把所有文档按type、date提取出的year和month共同分组,统计每个组合下的文档数量。这一步会自动合并同类型同年月的所有文档,得到单一的计数结果。
  2. 第二次分组:按类型聚合年月统计结果
    再将第一次分组的结果按type重新分组,把第一次分组得到的年月和count组合成对象,收集到byMonth数组中。

具体实现代码

$aggBuilder = $dm->createAggregationBuilder(Example::class);

// 保留你原来的时间范围匹配逻辑
$aggBuilder->match()
    ->field('date')
    ->gte($from)
    ->lte($to);

// 第一次分组:按 type + 年 + 月 组合分组,统计每个组合的文档数量
$aggBuilder->group()
    ->field('id')
    ->expression(
        $aggBuilder->expr()
            ->field('type')
            ->expression('$type')
            ->field('year')
            ->year('$date')
            ->field('month')
            ->month('$date')
    )
    ->field('count')
    ->sum(1);

// 第二次分组:仅按 type 分组,聚合年月统计结果到 byMonth 数组
$aggBuilder->group()
    ->field('id')
    ->expression(
        $aggBuilder->expr()
            ->field('type')
            ->expression('$id.type')
    )
    ->field('byMonth')
    ->push(
        $aggBuilder->expr()
            ->field('month')
            ->expression('$id.month')
            ->field('year')
            ->expression('$id.year')
            ->field('count')
            ->expression('$count')
    );

// 执行聚合查询
$result = $aggBuilder->getQuery()->execute();

最终输出效果

执行上述代码后,你会得到和预期完全一致的结果:

array(2) {
  ["_id"]=> array(1) { ["type"]=> string(1) "A" }
  ["byMonth"]=> array(3) {
    [0]=> array(3) { ["month"]=> int(7) ["year"]=> int(2025) ["count"]=> int(2) }
    [1]=> array(3) { ["month"]=> int(3) ["year"]=> int(2025) ["count"]=> int(2) }
    [2]=> array(3) { ["month"]=> int(1) ["year"]=> int(2025) ["count"]=> int(1) }
  }
}
array(2) {
  ["_id"]=> array(1) { ["type"]=> string(1) "B" }
  ["byMonth"]=> array(1) {
    [0]=> array(3) { ["month"]=> int(2) ["year"]=> int(2025) ["count"]=> int(1) }
  }
}

代码逻辑说明

  • 第一次$group阶段的_id同时包含type、year、month,确保每个唯一的组合只会生成一条统计记录,用sum(1)来累加该组合下的文档数量。
  • 第二次$group阶段仅按type分组,通过push将第一次分组得到的年月统计项整合到数组中,最终得到你想要的无重复嵌套分组结构。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 12:04:32