本文详解如何使用 spring data mongodb 的 mongotemplate 实现基于多个字段的 `$group` 聚合,并结合 `$max` 操作符提取每组最大 `_id`,提供可直接运行的 java 代码示例及关键注意事项。
在 Spring Data MongoDB 中,MongoTemplate 提供了类型安全、链式调用的聚合 API,但其语法与原生 MongoDB Shell 存在差异——尤其在字段路径表达和多字段分组场景下容易产生困惑。例如,原生查询中 “_id”: “$somefield.$id” 实际表示按嵌套字段 somefield.id 的值分组(注意:MongoDB 中 . 是字段路径分隔符,非 JS 对象访问语法),而非字面量 “somefield.$id”。对应到 Aggregation.group(),应传入标准点号路径 “somefield.id”。
以下为完整实现步骤:
1. 构建单字段分组 + 最大值聚合
若仅需按 somefield.id 分组并取每组 _id 的最大值,代码简洁直观:
AggregationOperation groupOp = Aggregation.group("somefield.id")
.max("_id").as("xyz");
⚠️ 注意:Aggregation.group(String… keys) 支持多字段分组(如 .group(“fieldA”, “fieldB”)),但此时 _id 将自动变为文档形式(如 { fieldA: “…”, fieldB: “…” })。而本例中 somefield.id 是单个路径表达式,因此 _id 为该字段的值(字符串或 ObjectId)。
2. 组装并执行聚合查询
Aggregation aggregation = Aggregation.newAggregation(groupOp);
AggregationResults results = mongoTemplate.aggregate(
aggregation,
"mycollection",
YourResultClass.class
);
List resultList = results.getMappedResults();
其中 YourResultClass 需包含 xyz 字段(类型需与 _id 匹配,通常为 String 或 ObjectId),例如: