如何使用MongoDB的$lookup关联集合并实现ri_score字段去重?
解决MongoDB聚合查询中关联数组的重复值问题
嘿,我来帮你搞定这个重复ri_score的问题!
问题出在你的$lookup阶段会把所有匹配uc_id的文档都关联过来,所以两个ri_score相同的条目都被保留了。要得到你期望的去重结果,只需要在聚合管道里加一步对关联数组的去重处理就行。
完整的聚合查询方案
db.first_collection.aggregate([ // 第一步:关联两个集合,获取所有匹配的文档 { $lookup: { from: "second_collection", localField: "UID", foreignField: "uc_id", as: "second_collection_docs" } }, // 第二步:对关联数组中的ri_score去重并重新格式化 { $addFields: { second_collection_docs: { $map: { // 用$addToSet提取唯一的ri_score值 input: { $addToSet: "$second_collection_docs.ri_score" }, as: "uniqueScore", // 把每个唯一值转回你需要的对象格式 in: { ri_score: "$$uniqueScore" } } } } }, // 第三步:保留需要的字段(可选,如果你只需要这三个字段的话) { $project: { "UID": 1, "name": 1, "second_collection_docs": 1 } } ])
方案说明
- $lookup阶段:和你原来的逻辑一样,把
second_collection中uc_id匹配first_collection的UID的文档全部关联到second_collection_docs数组里。 - $addFields阶段:
$addToSet: "$second_collection_docs.ri_score":从关联数组中提取所有ri_score的值,并自动去重,得到一个只包含唯一值的数组(比如["5.3"])。$map:把这个去重后的数组里的每个值,重新格式化成你需要的{ ri_score: 值 }对象结构。
- $project阶段:保留你需要的
UID、name和处理后的second_collection_docs字段,过滤掉不需要的内容。
这样执行后,返回的结果就会是你期望的:
{ "UID" : 3398, "name" : "test", "second_collection_docs" : [{ "ri_score" : "5.3" }] }
补充说明
如果你的ri_score是数值类型(比如原始数据里是5.3而不是字符串"5.3"),这个方案同样适用,$addToSet会正确识别数值的相等性进行去重。
内容的提问来源于stack exchange,提问作者Sushil Dubey
相关产品推荐
相关产品推荐

