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

Spring Data MongoDB按嵌套字段分组计数异常排查与修正

问题排查与修正

问题根源

你遇到的计数全部为1的问题,是因为错误地将全局$count阶段放在了分组阶段之后。Spring Data MongoDB的Aggregation.count()是生成独立的$count管道阶段,用于统计整个管道的最终文档总数,而非分组内的文档数量。正确的做法是在分组阶段内直接统计每组的文档数。

关键信息核对

1. 集合数据结构(示例)

{
  "_id": ObjectId("60d21b4667d0d8992e610c85"),
  "type": {
    "name": "视频"
  },
  "content": "示例内容"
}

2. 原错误代码

你的聚合管道可能如下:

Aggregation aggregation = Aggregation.newAggregation(
    Aggregation.group("type.name"),
    Aggregation.count().as("count") // 错误:独立的count阶段,每个分组仅返回1
);

AggregationResults<TypeCountDto> results = mongoTemplate.aggregate(
    aggregation,
    "content_collection",
    TypeCountDto.class
);

3. 正确的Mongo Shell管道

你在Shell中执行的正确逻辑:

db.content_collection.aggregate([
    { $group: { _id: "$type.name", count: { $sum: 1 } } }
])

该管道能正确返回每个类型的实际文档数。

4. 结果DTO类

public class TypeCountDto {
    @Field("_id")
    private String typeName;
    private Long count;

    // Getter、Setter、构造方法省略
}

5. 原执行日志(关键片段)

日志生成的错误管道:

[
  { "$group" : { "_id" : "$type.name" } },
  { "$count" : "count" }
]

第二个$count阶段会将每个分组的结果计数为1,这就是问题所在。

修正后的代码

将计数逻辑整合到GroupOperation中,使用分组阶段的count()方法(对应Mongo的$sum:1):

// 构建分组操作:按type.name分组,同时统计每组文档数量
GroupOperation groupByTypeName = Aggregation.group("type.name")
    .count().as("count");

Aggregation aggregation = Aggregation.newAggregation(groupByTypeName);

AggregationResults<TypeCountDto> results = mongoTemplate.aggregate(
    aggregation,
    "content_collection",
    TypeCountDto.class
);

验证修正效果

修正后生成的管道与Shell中的正确逻辑完全一致:

[
  { "$group" : { "_id" : "$type.name", "count" : { "$sum" : 1 } } }
]

此时每个type.name对应的count会正确统计该分组下的所有文档数量。

额外优化建议

  • 如果需要对结果按计数排序,可添加排序阶段:
SortOperation sortByCountDesc = Aggregation.sort(Sort.Direction.DESC, "count");
Aggregation aggregation = Aggregation.newAggregation(groupByTypeName, sortByCountDesc);
  • 确保DTO的typeName字段通过@Field("_id")正确映射分组的_id值,避免字段赋值为空。

内容的提问来源于stack exchange,提问作者unknowncodder

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 13:05:35