Mongodb MongoTemplate聚合未映射结果

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.发布版 我不确定我做错了什么 下面是聚合的代码

我正在尝试使用MongoTemplate和聚合框架在spring启动项目中运行聚合管道

我的查询毫无例外地执行。但是当我试图调用
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版本有关。不过,构建Spring
AggregationOperation
最好的方法是从调试日志中复制MongoDB查询,并在MongoShell中测试每个操作。无论如何,在升级了spring版本之后,它似乎可以工作了
{
  _id: {
    field1:"field1",
    field2:"field2"
  },
  count: countResult,
  timestamp:timestamp
}