MongoDB聚合关联数组内外部模型返回重复数据修复方法
问题原因
你的聚合逻辑有三处错误,直接导致匹配失效、重复数据:
- 字段名写错:MongoDB的主键字段是
_id,你在$indexOfArray里写的$productInterestData.id、$this.id都是不存在的字段,根本匹配不到正确的产品索引。 - 变量引用写错:
$map遍历的当前元素必须用$$this(双$前缀),单$this无法读取到当前遍历的数组项。 - 赋值路径写错:你给
product_types.product赋值$map的结果,相当于给整个product_types数组挂了一个公共属性,而不是给每个数组成员单独加关联的产品数据,最终结构错乱出现重复。
修正后的聚合语句
直接替换原有聚合即可,兼容MongoDB 3.4及以上版本:
db.getCollection('interests').aggregate([ { $lookup:{ from: "products", localField: "product_types.product_id", foreignField: "_id", as: "productInterestData" } }, { $set: { "product_types": { $map: { input: "$product_types", as: "item", in: { $mergeObjects: [ "$$item", { product: { $arrayElemAt: [ "$productInterestData", { $indexOfArray: ["$productInterestData._id", "$$item.product_id"] } ] } } ] } } } } }, {$unset: "productInterestData"} ])
返回结果说明
修正后每个product_types数组项只会关联到唯一匹配的产品对象,不会出现重复、错配,返回结构如下:
{ "_id" : ObjectId("62b489664cbb9bc8c947f19f"), "user_id" : ObjectId("61a775da4cbb9bc8c947edd9"), "product_types" : [ { "type" : NumberLong(1), "product_id" : ObjectId("62b4890f4cbb9bc8c947e5ef"), "product" : { "_id" : ObjectId("62b4890f4cbb9bc8c947e5ef"), "name" : "olive" } }, { "type" : NumberLong(1), "product_id" : ObjectId("62b4890f4cbb9bc8c947e5ed"), "product" : { "_id" : ObjectId("62b4890f4cbb9bc8c947e5ed"), "name" : "对应产品名称" } } ] }
如果你用的是MongoDB 5.0+版本,也可以直接用
$lookup的管道模式直接在关联阶段完成数组匹配,不需要后续手动合并,逻辑更简洁,但上面的写法覆盖绝大多数生产环境版本。
内容的提问来源于stack exchange,提问作者Adrien Chapelet
相关产品推荐
相关产品推荐

