MongoDB聚合:如何在$group后用$match统计目标用户的product-4数量
统计拥有product-1或product-2的用户的product-4数量
现有4款产品,需要统计拥有product-1或product-2的用户各自拥有的product-4数量,没有product-4的用户计数为0。
示例数据
[ { "user_id": 1, "product_type": "product-1" }, { "user_id": 1, "product_type": "product-4" }, { "user_id": 1, "product_type": "product-4" }, { "user_id": 2, "product_type": "product-1" } ]
按照需求,用户1拥有2个product-4,计数为2;用户2没有product-4,计数为0。
我尝试的聚合代码
db.collection.aggregate([ { $match: { product_type: { $in: [ "product-1", "product-2", ], }, }, }, { $group: { _id: "$user_id", }, }, { $match: { user_id: { $in: "$_id"}, // 希望在此使用$group的结果 product_type: "product-4", }, } ]);
这段代码无法实现需求,因为$match阶段不能直接引用上一个$group的_id值作为查询条件。
期望结果
[ { "_id": 1, "count": 2 }, { "_id": 2, "count": 0 } ]
正确的MongoDB聚合方案
要实现需求,需要先筛选出目标用户,再关联他们的product-4数据,具体步骤如下:
完整聚合代码
db.collection.aggregate([ // 筛选出拥有product-1或product-2的用户ID { $match: { product_type: { $in: ["product-1", "product-2"] } } }, { $group: { _id: "$user_id" } }, // 关联该用户所有的product-4记录 { $lookup: { from: "collection", // 替换为你的集合名称 let: { targetUserId: "$_id" }, pipeline: [ { $match: { $expr: { $and: [ { $eq: ["$user_id", "$$targetUserId"] }, { $eq: ["$product_type", "product-4"] } ] } } } ], as: "product4List" } }, // 统计product-4的数量,没有则为0 { $project: { _id: 1, count: { $size: "$product4List" } } } ])
代码说明
$group阶段先提取所有拥有product-1或product-2的用户ID;$lookup使用子查询,只关联当前用户的product-4记录,避免返回无关数据;$size直接计算关联数组的长度,没有product-4时数组为空,结果就是0,正好符合需求。
内容的提问来源于stack exchange,提问作者feyzullahyildiz
相关产品推荐
相关产品推荐

