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

MongoDB聚合管道:基于$lookup生成字段关联多集合统计数组匹配次数

MongoDB多集合关联聚合统计解决方案

你在聚合管道上一步生成的an_user_id字段可以直接被后续阶段调用,无需特殊处理,以下是完整实现方案:

完整聚合管道代码(pymongo适配)

pipeline = [
    # 原有逻辑:关联members和an_users获取用户ID映射
    {
        '$lookup': {
            'from': 'an_users',                   
            'localField': 'membershipNumber',     
            'foreignField': 'memref',             
            'as': 'an_users'                      
        }
    },
    {'$unwind' : '$an_users'},     
    {   
        '$project' : {
            'membershipNumber': 1,
            'an_user_id' : '$an_users.user_id'
        } 
    },
    # 新增:关联emails集合统计邮件操作次数
    {
        '$lookup': {
            'from': 'emails',
            'let': {'current_uid': '$an_user_id'},
            'pipeline': [
                # 过滤当前用户有操作记录的邮件
                {
                    '$match': {
                        '$expr': {
                            '$or': [
                                {'$in': ['$$current_uid', '$click']},
                                {'$in': ['$$current_uid', '$bounce']},
                                {'$in': ['$$current_uid', '$opens']}
                            ]
                        }
                    }
                },
                # 分组统计各操作的总次数
                {
                    '$group': {
                        '_id': None,
                        'n_email_clicks': {
                            '$sum': {'$cond': [{'$in': ['$$current_uid', '$click']}, 1, 0]}
                        },
                        'n_email_bounces': {
                            '$sum': {'$cond': [{'$in': ['$$current_uid', '$bounce']}, 1, 0]}
                        },
                        'n_email_opens': {
                            '$sum': {'$cond': [{'$in': ['$$current_uid', '$opens']}, 1, 0]}
                        }
                    }
                }
            ],
            'as': 'email_stats'
        }
    },
    # 展开邮件统计结果,无匹配记录的用户保留
    {
        '$unwind': {
            'path': '$email_stats',
            'preserveNullAndEmptyArrays': True
        }
    },
    # 新增:关联events集合统计活动报名次数
    {
        '$lookup': {
            'from': 'events',
            'let': {'current_uid': '$an_user_id'},
            'pipeline': [
                # 过滤当前用户报名的活动
                {'$match': {'$expr': {'$in': ['$$current_uid', '$rsvps.rsvp_user_id']}}},
                # 统计报名总次数
                {'$count': 'n_rsvps'}
            ],
            'as': 'event_stats'
        }
    },
    # 展开活动统计结果,无匹配记录的用户保留
    {
        '$unwind': {
            'path': '$event_stats',
            'preserveNullAndEmptyArrays': True
        }
    },
    # 最终格式化输出字段,缺失统计值默认补0
    {
        '$project': {
            'membershipNumber': 1,
            'an_user_id': 1,
            'n_email_clicks': {'$ifNull': ['$email_stats.n_email_clicks', 0]},
            'n_email_bounces': {'$ifNull': ['$email_stats.n_email_bounces', 0]},
            'n_email_opens': {'$ifNull': ['$email_stats.n_email_opens', 0]},
            'n_rsvps': {'$ifNull': ['$event_stats.n_rsvps', 0]}
        }
    }
    # 若需要生成物理集合,取消下方注释,集合名可自行修改
    # , {'$out': 'user_member_statistics'}
]

# 执行聚合查询
result = members.aggregate(pipeline)

# 若需要生成实时查询视图(无物理存储),使用下方代码:
# db.create_view('user_member_stats_view', 'members', pipeline)

关键逻辑说明

  • 管道执行规则:MongoDB聚合管道按阶段顺序执行,前序阶段输出的所有字段(包括计算生成的an_user_id)都可以直接作为后续操作的参数使用,无需额外适配。
  • 子管道$lookup优势:通过let传参+子管道过滤统计的方式,避免全量拉取关联集合数据后再处理,大幅提升大数量级下的查询效率。
  • 空值兼容:preserveNullAndEmptyArrays参数和$ifNull运算符配合,保证没有操作记录的用户不会被过滤,统计结果更完整。
  • 结果持久化选择:
    • 数据量不大、需要实时查询的场景优先使用视图,无需占用额外存储空间。
    • 数据量大、需要离线分析的场景使用$out生成物理集合,查询性能更高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 11:36:07