MongoDB聚合中$lookup与$match组合报错‘必须仅包含一个字段’
问题解决方法
错误原因
你把$match和$lookup放在了同一个聚合阶段对象里,MongoDB要求每个聚合阶段必须是独立的对象(每个阶段对应一个{}),所以才会报错"A pipeline stage specification object must contain exactly one field"。
修正后的基础代码
先拆分阶段,让$match和$lookup各自成为独立的聚合阶段:
db.NealTestBay.aggregate([ // 第一个阶段:筛选type为parent的文档 { "$match": { type: "parent" } }, // 第二个阶段:关联同集合的文档 { "$lookup": { "from": "NealTestBay", "localField": "toSku", "foreignField": "toSku", "as": "grp" } } ])
满足需求的优化代码
上面的代码会关联所有toSku相同的文档,但你需要只关联type为child的,这时候要改用$lookup的pipeline模式(注意:使用pipeline时确实不能同时用localField和foreignField,需要用let传递变量,再用$expr匹配字段):
db.NealTestBay.aggregate([ { "$match": { type: "parent" } }, { "$lookup": { "from": "NealTestBay", "let": { parentToSku: "$toSku" }, // 传递当前parent文档的toSku "pipeline": [ { "$match": { "$expr": { "$eq": ["$toSku", "$$parentToSku"] }, // 匹配toSku "type": "child" // 筛选type为child的文档 } } ], "as": "grp" } } ])
额外说明
如果后续需要对关联的grp数组做求和等操作,可以在$lookup之后添加$addFields或$project阶段,比如计算child文档的某个字段总和:
db.NealTestBay.aggregate([ { "$match": { type: "parent" } }, { "$lookup": { "from": "NealTestBay", "let": { parentToSku: "$toSku" }, "pipeline": [ { "$match": { "$expr": { "$eq": ["$toSku", "$$parentToSku"] }, "type": "child" } } ], "as": "grp" } }, { "$addFields": { "childTotal": { "$sum": "$grp.amount" } // 假设child文档有amount字段,求和 } } ])
内容的提问来源于stack exchange,提问作者NealWalters
相关产品推荐
相关产品推荐

