能否使用MongoDB的$lookup拼接$facet输出的两个聚合管道结果?
问题解答
首先明确结论:可以用$lookup实现,但属于过度操作,直接使用MongoDB内置数组操作即可更高效的完成需求,完全不需要调用关联查询能力。
最优实现方案(无$lookup,性能最优)
在你现有$facet聚合阶段的后面,追加如下3个聚合阶段即可得到目标结果:
- 拆分
pipe1数组为单条独立文档
{ "$unwind": "$pipe1" }
- 从
pipe2数组中匹配同_id的sum字段,写入pipe1对象中
{ "$addFields": { "pipe1.sum": { "$getField": { "input": { "$first": { "$filter": { "input": "$pipe2", "cond": { "$eq": ["$$this._id", "$pipe1._id"] } } } }, "field": "sum" } } } }
- 将
pipe1对象提取为最终根文档
{ "$replaceRoot": { "newRoot": "$pipe1" } }
$lookup实现方案(不推荐)
$lookup本身是设计用于跨集合关联查询的,用在同文档数组拼接场景性能远低于上述数组操作方案,实现方式如下(需要MongoDB 5.0及以上版本支持):
// 1. 拆分pipe1数组 { "$unwind": "$pipe1" }, // 2. 调用$lookup匹配pipe2数据 { "$lookup": { "let": { "current_id": "$pipe1._id", "pipe2_arr": "$pipe2" }, "pipeline": [ // 用传入的pipe2数组作为数据源,无需关联真实集合 { "$documents": "$$pipe2_arr" }, { "$match": { "$expr": { "$eq": ["$_id", "$$current_id"] } } } ], "as": "matched_pipe2" } }, // 3. 合并sum字段到pipe1 { "$addFields": { "pipe1.sum": { "$arrayElemAt": ["$matched_pipe2.sum", 0] } } }, // 4. 提取为最终根文档 { "$replaceRoot": { "newRoot": "$pipe1" } }
内容的提问来源于stack exchange,提问作者Noa Be
相关产品推荐
相关产品推荐

