MongoDB聚合查询求助:统计被收藏食物的收藏人数
解决方案
方法一:从用户集合统计后关联食物信息
db.users.aggregate([ // 展开每个用户的收藏食物数组,每条记录对应一个收藏项 { $unwind: "$favouriteFoods" }, // 按食物ID分组,统计被收藏的次数(即收藏人数) { $group: { _id: "$favouriteFoods", numberOfFavourites: { $sum: 1 } } }, // 关联foods集合,获取对应食物的名称 { $lookup: { from: "foods", localField: "_id", foreignField: "_id", as: "foodDetail" } }, // 展开关联得到的食物信息数组(每个ID仅匹配一条数据) { $unwind: "$foodDetail" }, // 重构输出字段,保留需要的内容 { $project: { _id: "$foodDetail._id", name: "$foodDetail.name", numberOfFavourites: 1 } } ])
方法二:从食物集合出发,直接统计收藏人数
db.foods.aggregate([ // 关联users集合,筛选出所有收藏当前食物的用户 { $lookup: { from: "users", let: { targetFoodId: "$_id" }, pipeline: [ { $match: { $expr: { $in: ["$$targetFoodId", "$favouriteFoods"] } } } ], as: "favouriters" } }, // 可选:过滤掉从未被收藏的食物,若需要保留则删除此阶段 { $match: { favouriters: { $ne: [] } } }, // 统计收藏人数,即关联得到的用户数组长度 { $project: { _id: 1, name: 1, numberOfFavourites: { $size: "$favouriters" } } } ])
简单说明
- 方法一先拆解用户的收藏列表统计次数,再关联食物名称,适合用户量不大但收藏数组较多的场景。
- 方法二从食物角度出发,用带条件的lookup找到所有收藏者,再统计数量,逻辑更直观,还可以轻松保留未被收藏的食物(去掉
$match阶段即可)。
内容的提问来源于stack exchange,提问作者Amir Daniel
相关产品推荐
相关产品推荐

