MongoDB多字段匹配查询重复文档的Java MongoTemplate实现
问题根因
你当前的聚合逻辑存在两个核心缺陷:
- 分组维度错误:仅按
VIN单字段分组,未将CUSTOMER_TYPE、CUSTOMER_FIRST_NAME纳入分组键,不符合三个字段取值完全一致才算重复的业务判定规则 - 分组阶段仅做计数统计,没有保留原始文档的完整引用,聚合执行到分组步骤后就丢失了除分组键、计数字段外的所有原始内容,自然无法返回完整文档。
调整后的实现逻辑
要获取符合重复规则的完整原始文档,聚合管道按4个步骤配置即可:
- 按三个目标字段做组合分组:分组键同时包含
VIN、CUSTOMER_TYPE、CUSTOMER_FIRST_NAME,分组时通过$$ROOT系统变量把匹配到的完整原始文档存入结果集,同时统计分组内的文档数量 - 筛选重复分组:匹配分组内文档数
count > 1的分组,即三个字段取值完全相同的重复数据组 - 拆分文档数组:把分组阶段存储的原始文档数组拆分为单条文档结构
- 替换根节点:把拆分后的原始文档提升为聚合结果的顶层节点,直接输出无字段缺失的完整原始文档。
对应Java代码实现(基于Spring Data MongoDB聚合框架)
import org.springframework.data.mongodb.core.aggregation.Aggregation; import org.springframework.data.mongodb.core.aggregation.AggregationResults; import org.springframework.data.mongodb.core.query.Criteria; import java.util.List; // 构建聚合管道 Aggregation aggregation = Aggregation.newAggregation( // 第一步:三字段组合分组,统计重复数、保留全量原始文档 Aggregation.group("VIN", "CUSTOMER_TYPE", "CUSTOMER_FIRST_NAME") .count().as("dupCount") .push("$$ROOT").as("originDocs"), // 第二步:筛选存在重复的分组 Aggregation.match(Criteria.where("dupCount").gt(1)), // 第三步:拆分存储原始文档的数组 Aggregation.unwind("originDocs"), // 第四步:将原始文档替换为结果根节点,输出完整字段 Aggregation.replaceRoot("originDocs") ); // 执行聚合查询,用对应实体类接收结果 AggregationResults<CustomerFinance> results = mongoTemplate.aggregate( aggregation, "customerFinance", CustomerFinance.class ); List<CustomerFinance> duplicateDocs = results.getMappedResults();
执行上述代码后,返回结果就是目标的两条完整文档:VIN=100、CUSTOMER_TYPE为1-PRIMARY BORROWER、CUSTOMER_FIRST_NAME为MATT的LEASE合约、RETAIL合约记录,所有原始字段无缺失。
内容的提问来源于stack exchange,提问作者Srinivasan Ramu
相关产品推荐
相关产品推荐

