You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Data MongoDB自定义ReactiveMongoTemplate聚合结果无法映射DTO

问题根因

你自定义的ReactiveMongoQueryTemplate没有注入Spring Data MongoDB默认的MappingMongoConverter,直接初始化的模板仅使用极简转换器,不支持以下默认映射能力:

  • 自动将Mongo返回的_id字段映射到Java类的id字段
  • 自动完成Mongo ISODate类型到Java OffsetDateTime类型的转换
    映射失败的元素会被响应式流静默过滤,因此不会抛出错误也没有返回结果。
    另外你的Java代码中排序规则和原生Mongo语句相反,会导致分组取到的last值不符合预期,不属于映射失效的原因但需要修正。

解决方案

1. 修正自定义MongoTemplate配置

给自定义模板注入官方提供的映射转换器,保留默认的映射、类型转换能力:

@Configuration
class MultipleMongoConfig {

    private final CustomMongoProperties customMongoProperties;
    // 注入Spring自动配置好的映射转换器
    private final MappingMongoConverter mappingMongoConverter;

    public MultipleMongoConfig(CustomMongoProperties customMongoProperties, MappingMongoConverter mappingMongoConverter) {
        this.customMongoProperties = customMongoProperties;
        this.mappingMongoConverter = mappingMongoConverter;
    }

    @Bean
    public MongoClient reactiveMongoQueryClient() {
        return MongoClients.create(createMongoClientSettings(customMongoProperties.getQuery()));
    }

    @Bean("mongoQueryTemplate")
    public ReactiveMongoTemplate reactiveMongoQueryTemplate() {
        ReactiveMongoTemplate template = new ReactiveMongoTemplate(reactiveMongoQueryClient(), 
                customMongoProperties.getQuery().getDatabase());
        // 给模板设置映射转换器
        template.setConverter(mappingMongoConverter);
        return template;
    }

    private MongoClientSettings createMongoClientSettings(MongoProperties mongoProperties) {
        ConnectionString connectionString = new ConnectionString(mongoProperties.getUri());
        return MongoClientSettings.builder()
                .readConcern(ReadConcern.DEFAULT)
                .writeConcern(WriteConcern.MAJORITY)
                .readPreference(ReadPreference.primary())
                .applyConnectionString(connectionString)
                .build();
    }
}

如果你定义的ReactiveMongoQueryTemplate是继承ReactiveMongoTemplate的自定义子类,确保父类的setConverter方法没有被重写屏蔽。

2. DTO增加显式字段映射(可选兜底)

可以给DTO字段加@Field注解显式指定映射关系,避免配置异常导致的映射失败:

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ProjectionProperty {
    @Field("_id")
    private String id;
    private String value;
    private OffsetDateTime issuedAt;
}

3. 修正排序规则

将Java代码中的排序规则调整为和原生Mongo语句一致:

Aggregation.sort(Direction.ASC, PRIORITY)
        .and(Direction.DESC, ISSUED_AT)

调试技巧

如果后续再遇到类似无返回无报错的问题,可以先将聚合结果转为org.bson.Document类型打印原始返回,确认数据已经正常从Mongo查询返回,再定位映射环节问题:

reactiveMongoQueryTemplate.aggregate(aggregation, Document.class)
        .doOnNext(doc -> System.out.println("原始返回结果:" + doc))
        .collectList();

内容的提问来源于stack exchange,提问作者Bert Roex

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 01:39:05