You need to enable JavaScript to run this app. Spring MongoTemplate如何统计projectCategories的唯一值及出现次数
优惠活动
大模型
产品
解决方案
定价
更多

Spring MongoTemplate如何统计projectCategories的唯一值及出现次数

完全可以通过Spring MongoTemplate实现该需求,核心是借助MongoDB的$objectToArray聚合操作符处理动态键的projectCategories对象,再配合展开、分组统计即可完成。

实现思路
  • 第一步:通过$objectToArray将projectCategories的键值对象转换为[{k: "键", v: "值"}, ...]格式的数组
  • 第二步:通过$unwind展开上述数组,让每个分类值单独对应一条文档
  • 第三步:通过$group按分类值(也就是数组元素的v字段)分组,用$sum统计出现次数
  • 可选步骤:通过$sort按统计次数排序,方便查看结果
代码实现

首先定义结果接收DTO:

import lombok.Data;

@Data
public class CategoryCountDTO {
    // 分类名称
    private String categoryName;
    // 出现次数
    private Long count;
}

然后编写MongoTemplate聚合查询逻辑:

import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;
import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;
import static org.springframework.data.mongodb.core.aggregation.ObjectOperators.ObjectToArray;

@Component
public class ProjectCategoryStatistic {
    @Resource
    private MongoTemplate mongoTemplate;

    public List<CategoryCountDTO> getCategoryCount() {
        Aggregation aggregation = newAggregation(
                // 可选:提前过滤没有分类字段的无效文档,提升查询效率
                match(Criteria.where("projectCategories").exists(true).ne(null)),
                // 将projectCategories对象转为数组
                project().and(ObjectToArray.valueOf("projectCategories")).as("categoryArr"),
                // 展开分类数组
                unwind("categoryArr"),
                // 按分类值分组统计次数
                group("categoryArr.v").count().as("count"),
                // 映射字段,适配DTO结构
                project()
                        .and("_id").as("categoryName")
                        .and("count").as("count")
                        .exclude("_id"),
                // 可选:按出现次数倒序排序
                sort(Sort.Direction.DESC, "count")
        );
        // 若你有对应集合的实体类,也可将第二个参数替换为实体类.class,不需要手写集合名
        AggregationResults<CategoryCountDTO> result = mongoTemplate.aggregate(aggregation, "你的集合名", CategoryCountDTO.class);
        return result.getMappedResults();
    }
}
注意事项
  • 10万条数据量级下该聚合执行效率很高,常规配置的MongoDB实例单次查询耗时在百毫秒级别
  • 如果projectCategories存在空对象的情况,可在match阶段补充ne(new HashMap<>())过滤空值

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.13 16:18:00