Mongodb MongoTemplate聚合未映射结果
我正在尝试使用MongoTemplate和聚合框架在spring启动项目中运行聚合管道 我的查询毫无例外地执行。但是当我试图调用Mongodb MongoTemplate聚合未映射结果,mongodb,spring-boot,spring-data,spring-mongodb,Mongodb,Spring Boot,Spring Data,Spring Mongodb,我正在尝试使用MongoTemplate和聚合框架在spring启动项目中运行聚合管道 我的查询毫无例外地执行。但是当我试图调用AggregationResults实例上的getMappedResults()时,它总是给我一个空列表。但是,如果我在调试器中检查结果,我可以看到getRawResults()方法返回值 我正在使用spring boot版本1.5.9.发布版和spring boot starter数据mongodb版本2.1.2.发布版 我不确定我做错了什么 下面是聚合的代码
AggregationResults
实例上的getMappedResults()
时,它总是给我一个空列表。但是,如果我在调试器中检查结果,我可以看到getRawResults()
方法返回值
我正在使用spring boot版本1.5.9.发布版和spring boot starter数据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);
注意 如果在聚合选项中跳过光标,则会出现以下错误
'The 'cursor' option is required, except for aggregate with the explain argument'
根据我的经验,
GroupOperation
将生成一系列具有以下方案的文档:
{
_id: {
field1:"field1",
field2:"field2"
},
count: countResult,
timestamp:timestamp
}
在这种情况下,ProjectOperation
不会生成映射实体类的文档
我建议您通过在application.properties
文件中添加logging.level.org.springframework.data=debug
来激活调试日志记录。通过这种方式,您可以查看发送到MongoDB的请求,并在MongoShell中重新生成它们,以便查看每个聚合操作的结果
测试由于GroupOperation
结果而导致实体类未正确映射的假设的一种快速方法是添加Setters
并删除第二个构造函数count
和timestamp
属性应正确映射,并且将仅使用count
和timestamp
属性创建Res
对象
注意:聚合需要光标,因为Mongo 3.6和MongoDB 3.6需要spring 1.5.10.RELEASE进行聚合操作。Concider将Spring boot升级到1.5.10以跳过光标。我也遇到了聚合不映射复合ID的问题,结果我误解了映射的工作原理。(我建议阅读关于映射的Spring文档:)
还值得注意的是,映射行为在SpringBoot2.1.8和2.3.4之间发生了变化(我只是在升级时遇到了这个问题)。在2.1.8中,您可以正确或错误地将复合键映射到单个java类中的不同字段(例如问题中发布的原始Res类)
charlycou的回答在返回的文档的代码片段中提供了线索(注意_id是一个json对象)
{
_身份证:{
字段1:“字段1”,
字段2:“字段2”
},
count:countResult,
时间戳:时间戳
}
为了使映射在这个复合键场景中正常工作,请创建一个java类来表示复合键。例如:
公共类剩余{
公共字符串字段1;
公共字符串字段2;
公共剩余(字符串字段1、字符串字段2){
此字段1=字段1;
this.field2=field2;
}
}
公共类资源{
@身份证
公共住宅;
公共长时间戳;
公共整数计数;
公共资源(){
}
公共资源(剩余资源、长时间戳、整数计数){
这个。剩余=剩余;
this.timestamp=时间戳;
this.count=计数;
}
}
我尝试了您的建议,添加了setter并删除了所有构造函数,但没有删除默认构造函数。然而,它仍然没有映射结果。但当我升级到Spring1.5.10时,它就开始工作了。我不确定这是否是spring版本特有的问题。您是否按照我的建议修改了ProjectOperation
?也不确定这与Spring版本有关。不过,构建SpringAggregationOperation
最好的方法是从调试日志中复制MongoDB查询,并在MongoShell中测试每个操作。无论如何,在升级了spring版本之后,它似乎可以工作了
{
_id: {
field1:"field1",
field2:"field2"
},
count: countResult,
timestamp:timestamp
}