You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MongoDB聚合查询如何跨集合关联获取其他集合数据

MongoDB聚合关联post集合实现方案

你可以直接在原有聚合管道的$project阶段后、$sort阶段前,插入$lookup关联和字段提取逻辑,无需改动原有已实现的统计逻辑,且分组后再做关联的性能远高于在明细阶段关联。

完整修改后的聚合代码

db.Vote.aggregate([
    {
        $match: {
            surveyId: "e6d38e1ecd",
            "comment.topic": {
                $exists: 1
            },
        }
    },
    {
        $group: {
            _id: {
                topic: "$comment.topic",
                text_sentiment: "$comment.text_sentiment"
            },
            total: {
                $sum: 1
            },
            postIds: {
                $push: "$postId"
            }
        }
    },
    {
        $group: {
            _id: "$_id.topic",
            total: {
                $sum: "$total"
            },
            text_sentiments: {
                $push: {
                    k: "$_id.text_sentiment",
                    v: "$total"
                }
            },
            postIds: {
                "$push": "$postIds"
            }
        }
    },
    {
        $project: {
            topic: "$_id",
            topicOccurance: "$total",
            sentiment: {
                "$arrayToObject": "$text_sentiments"
            },
            postIds: {
                $reduce: {
                  input: "$postIds",
                  initialValue: [],
                  in: {
                    $concatArrays: [
                      "$$value",
                      "$$this"
                    ]
                  }
                }
            }
        }
    },
    // 新增的关联、字段处理阶段
    {
        $lookup: {
            from: "post", // 若你的post集合实际名称为posts,修改此处即可
            localField: "postIds",
            foreignField: "_id",
            as: "matchedPosts"
        }
    },
    {
        $project: {
            topic: 1,
            topicOccurance: 1,
            // 补全三类情感默认值,避免无数据时字段缺失
            sentiment: {
                $mergeObjects: [
                    { positive: 0, negative: 0, neutral: 0 },
                    "$sentiment"
                ]
            },
            // 对postId去重
            postIds: { $setUnion: ["$postIds", []] },
            // 提取关联到的post分类并去重
            categories: { $setUnion: ["$matchedPosts.category", []] }
        }
    },
    // 原有排序逻辑
    {
        $sort: {
            "topicOccurance": -1
        }
    }
])

关键逻辑说明

  • $lookup阶段直接用分组后得到的postIds数组关联post集合的_id字段,MongoDB会自动匹配数组中所有id对应的post文档,不需要额外写关联条件
  • 用$mergeObjects给情感统计字段补默认值,保证即使某类情感没有对应数据,返回结果里也会存在positive/negative/neutral三个字段,值为0
  • 用$setUnion对postIds和categories做去重处理,避免同一个post、同一个分类因为对应多条同主题评论重复出现在结果数组中
  • 关联逻辑放在两次分组之后执行,仅需要对最终返回的主题结果做关联,不需要逐一对每条Vote评论做关联,数据量越大性能优势越明显
  • 请保证Vote.postId和post._id的字段类型一致,若一边是字符串一边是对象ID/数字,会导致关联匹配失败

内容的提问来源于stack exchange,提问作者Suhail Gupta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 14:03:19