Spring MongoDB聚合查询无法获取指定字段重复值列表求助
Spring MongoDB聚合查询问题修复
问题场景
现有如下MongoDB数据集:
[ { "_id": 1, "domainName": "test1.com", "hosting": "hostgator.com", "to": "nanjing", "travelDate": "09/06/2022", "trainNumber": 123 }, { "_id": 2, "domainName": "test2.com", "hosting": "aws.amazon.com", "to": "beijing", "travelDate": "09/02/2022", "trainNumber": 123 }, { "_id": 3, "domainName": "test3.com", "hosting": "aws.amazon.com" }, { "_id": 4, "domainName": "test4.com", "hosting": "hostgator.com", "to": "shanghai", "travelDate": "09/06/2022", "trainNumber": 1234 }, { "_id": 5, "domainName": "test5.com", "hosting": "aws.amazon.com", "to": "wuhan", "travelDate": "09/06/2022", "trainNumber": 1234 }, { "_id": 6, "domainName": "test6.com", "hosting": "cloud.google.com", "to": "nanjing", "travelDate": "09/06/2022", "trainNumber": 123 }, { "_id": 7, "domainName": "test7.com", "hosting": "aws.amazon.com", "to": "nanjing", "travelDate": "09/02/2022", "trainNumber": 123 }, { "_id": 8, "domainName": "test8.com", "hosting": "hostgator.com", "to": "nanjing", "travelDate": "09/02/2022", "trainNumber": 123 }, { "_id": 9, "domainName": "test9.com", "hosting": "cloud.google.com", "to": "nanjing", "travelDate": "09/02/2022", "trainNumber": 123 }, { "_id": 10, "domainName": "test10.com", "hosting": "godaddy.com", "to": "nanjing", "travelDate": "09/02/2022", "trainNumber": 123 } ]
使用原生MongoDB聚合查询,可正确获取符合条件的to字段列表(包含重复值):
db.collection.aggregate({ $match: { travelDate: { $eq: "09/06/2022" }, trainNumber: { $eq: 1234 } } }, { $group: { _id: "", destStations: { $push: "$to" } } }, { $project: { _id: 0 } })
预期结果:
[ { "destStations": [ "shanghai", "wuhan" ] } ]
但使用以下Spring MongoDB聚合代码无法得到正确结果:
Aggregation agg = newAggregation( match(Criteria.where("travelDate").is(travelDate).and("trainNumber").is(trainNumber)), group("id").push("to").as("destStations"), project().andExclude("id") );
错误原因
- 分组逻辑不匹配:原生查询中
$group的_id设为空字符串,会将所有匹配$match条件的文档合并为一个分组;而Spring代码中group("id")实际是按文档的_id字段分组,导致每个匹配文档单独成组,无法得到合并后的列表。 - 投影排除字段错误:原生查询排除的是MongoDB默认主键
_id,但Spring代码中andExclude("id")对应的是不存在的id字段,导致最终结果仍会包含分组后的_id。
修正后的代码
将分组条件改为空字符串,并修正投影排除的字段:
Aggregation agg = newAggregation( match(Criteria.where("travelDate").is(travelDate).and("trainNumber").is(trainNumber)), group("").push("to").as("destStations"), project().andExclude("_id") );
验证结果
修正后的代码执行后,将返回与原生查询完全一致的结果:
[ { "destStations": [ "shanghai", "wuhan" ] } ]
内容的提问来源于stack exchange,提问作者SSM Tariq
相关产品推荐
相关产品推荐

