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

如何将MongoDB去重国家信息的聚合查询转为Spring Reactive Mongo实现

正确Spring Reactive MongoDB聚合实现

核心问题说明

你原有代码存在两处不符合需求的问题:

  • 错误添加了语法不正确且不匹配需求的match过滤条件
  • group阶段逻辑和原生查询不一致,没有按countryCode+countryName组合字段分组去重

实现代码

场景1:无过滤条件,查询全量去重的国家编码+名称

import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.stereotype.Repository;
import reactor.core.publisher.Flux;
import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;

@Repository
public class AggregateQueryRepository {
    
    private final ReactiveMongoTemplate reactiveMongoTemplate;

    // 推荐用构造注入替代@Autowired
    public AggregateQueryRepository(ReactiveMongoTemplate reactiveMongoTemplate) {
        this.reactiveMongoTemplate = reactiveMongoTemplate;
    }
    
    public Flux<Location> getAllCountryCodeAndCountry() {
        Aggregation aggregation = newAggregation(
                // 按countryCode和countryName组合分组,天然实现去重,和原生查询逻辑完全一致
                group("countryCode", "countryName"),
                // 将分组后嵌套在_id内的字段映射为Location实体的对应属性
                project()
                        .and("_id.countryCode").as("countryCode")
                        .and("_id.countryName").as("countryName")
        );
        return reactiveMongoTemplate.aggregate(aggregation, "location", Location.class);
    }
}

场景2:支持按传入的countryCode、countryName参数过滤后再去重

import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.stereotype.Repository;
import reactor.core.publisher.Flux;
import java.util.ArrayList;
import java.util.List;
import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;

@Repository
public class AggregateQueryRepository {
    
    private final ReactiveMongoTemplate reactiveMongoTemplate;

    public AggregateQueryRepository(ReactiveMongoTemplate reactiveMongoTemplate) {
        this.reactiveMongoTemplate = reactiveMongoTemplate;
    }
    
    public Flux<Location> getAllCountryCodeAndCountry(String countryCode, String countryName) {
        List<AggregationOperation> operations = new ArrayList<>();
        // 动态拼接过滤条件,参数不为空时才生效
        Criteria criteria = new Criteria();
        if (countryCode != null) {
            criteria.and("countryCode").is(countryCode);
        }
        if (countryName != null) {
            criteria.and("countryName").is(countryName);
        }
        if (!criteria.getCriteriaObject().isEmpty()) {
            operations.add(match(criteria));
        }
        // 分组去重
        operations.add(group("countryCode", "countryName"));
        // 字段映射
        operations.add(project()
                .and("_id.countryCode").as("countryCode")
                .and("_id.countryName").as("countryName"));

        Aggregation aggregation = newAggregation(operations);
        return reactiveMongoTemplate.aggregate(aggregation, "location", Location.class);
    }
}

注意事项

请确保你的Location实体类中存在countryCode和countryName两个属性,且有对应的get/set方法,否则字段映射会失败。

内容的提问来源于stack exchange,提问作者Mira Devi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 12:45:03