我正在尝试使用 MongoTemplate
和聚合框架在Spring Boot项目中运行聚合管道。
我的查询无任何例外地执行。但是,当我尝试在getMappedResults()
实例上调用AggregationResults
时,它总是给我一个空列表。但是,如果我在调试器中检查结果,则可以看到getRawResults()
方法返回了值。
我正在使用 spring-boot 版本 1.5.9.RELEASE 和 spring-boot-starter-data-mongodb 版本 2.1.2。发布
我不确定自己做错了什么。
以下是汇总代码
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'
答案 0 :(得分:1)
我还为聚合问题而苦苦挣扎,因为它没有映射复合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;
}
}
答案 1 :(得分:0)
根据我的经验,GroupOperation
将使用以下方案生成一系列文档:
{
_id: {
field1:"field1",
field2:"field2"
},
count: countResult,
timestamp:timestamp
}
在这种情况下,ProjectOperation
将不会生成映射您的实体类的文档。
我建议您通过在logging.level.org.springframework.data=debug
文件中添加application.properties
来激活调试日志记录。这样,您可以查看将哪些请求发送到MongoDB并在MongoShell中重现它们,以查看每个聚合操作的结果。
测试GroupOperation
结果导致实体类未正确映射的假设的一种快速方法是添加Setters
并删除第二个Constructor
。 count
和timestamp
属性应该正确映射,并且Res
对象只能使用count
和timestamp
属性创建。
注意:From this post,聚合需要使用游标,因为Mongo 3.6和MongoDB 3.6需要spring 1.5.10.RELEASE进行聚合操作。考虑将Spring-boot升级到1.5.10以跳过光标。