mongodb - MongoTemplate 聚合未映射结果
问题描述
我正在尝试使用MongoTemplate
聚合框架在 Spring Boot 项目中运行聚合管道。
我的查询毫无例外地执行。但是当我尝试调用实例getMappedResults()
时AggregationResults
,它总是给我一个空列表。但是,如果我在调试器中检查结果,我可以看到该getRawResults()
方法返回了值。
我正在使用spring-boot版本1.5.9.RELEASE和spring-boot-starter-data-mongodb版本2.1.2.RELEASE
我不确定我做错了什么。
以下是聚合的代码
GroupOperation groupOperation = Aggregation.group("field1", "field2")
.count().as("count")
.max("timestamp").as("timestamp");
ProjectionOperation projectionOperation = Aggregation.project("field1", "field2", "count", "timestamp");
DBObject cursor = new BasicDBObject(10);
AggregationOptions aggregationOptions = Aggregation.newAggregationOptions().cursor(cursor).build();
Aggregation aggregation = Aggregation.newAggregation(groupOperation, projectionOperation).withOptions(aggregationOptions);
AggregationResults<Res> activities = mongoTemplate.aggregate(aggregation, "test_collection", Res.class);
以下是我试图在其中映射结果的类
public class Res {
public String field1;
public String field2;
public Long timestamp;
public Integer count;
public Res() {
}
public Res(String field1, String field2, Long timestamp, Integer count) {
this.field1 = field1;
this.field2 = field2;
this.timestamp = timestamp;
this.count = count;
}
}
注意
如果我跳过光标AggregationOptions
,我会收到以下错误
'The 'cursor' option is required, except for aggregate with the explain argument'
解决方案
我也在努力解决聚合而不是映射复合 ID 的问题,结果我误解了映射的工作原理。(我建议阅读有关映射的 Spring 文档:https ://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#mapping-chapter )
还值得注意的是,映射行为在 Spring Boot 2.1.8 和 2.3.4 之间发生了变化(我只是在升级时遇到了这个问题)。在 2.1.8 中,无论对错,您都可以将复合键映射到单个 java 类中的不同字段(例如问题中发布的原始 Res 类)。
charlycou 的回答在返回的文档的代码片段中提供了线索(注意 _id 是一个 json 对象)
{
_id: {
field1:"field1",
field2:"field2"
},
count: countResult,
timestamp:timestamp
}
为了使映射在此复合键场景中正常工作,请创建一个 java 类来表示复合键。例如:
public class ResId {
public String field1;
public String field2;
public ResId(String field1, String field2){
this.field1 = field1;
this.field2 = field2;
}
}
public class Res {
@Id
public ResId resId;
public Long timestamp;
public Integer count;
public Res() {
}
public Res(ResId resId, Long timestamp, Integer count) {
this.resId = resId;
this.timestamp = timestamp;
this.count = count;
}
}
推荐阅读
- java - 我可以使用 JPA 将多个数据库表映射到一个唯一实体吗?
- swiftui - SwiftUI 文本高度上下扩展。我如何只花费底部
- c# - ChromeDriver / Selenium 不允许 gmail 登录
- python - psycpg2 插入失败
- php - PHP表单为2个不同的字段输入相同的值
- html - 通过单击背景来防止模式被隐藏是否违反了可访问性要求?
- excel - 需要关于嵌套 If 函数的指导
- reactjs - React-Apollo-Hooks 使用Mutation 传递空变量?
- swagger - 合并多个 swagger 文件
- python - 运行使用多个 conda 环境的烧瓶应用程序