如何在MongoDB查询中添加另一集合的匹配文档计数
如何查询公寓详情并附带收藏次数
我有两个MongoDB集合:
- Apartments:存储公寓基础信息
- Users:存储用户信息,其中
favorites字段是用户收藏的公寓ID数组
集合数据
Apartments集合
{_id: '1', address: 'Street 1'}, {_id: '2', address: 'Street 2'}, {_id: '3', address: 'Street 3'}, {_id: '4', address: 'Street 4'}
Users集合
{_id: '1', name: 'User 1', favorites: ['1', '3']}, {_id: '2', name: 'User 2', favorites: ['2', '3', '4']}, {_id: '3', name: 'User 3', favorites: []}
需求
返回每一条公寓详情的同时,新增favoritesCount字段,统计该公寓ID在所有用户favorites数组中的出现次数,期望结果如下:
{_id: '1', address: 'Street 1', favoritesCount: 1}, {_id: '2', address: 'Street 2', favoritesCount: 1}, {_id: '3', address: 'Street 3', favoritesCount: 2}, {_id: '4', address: 'Street 4', favoritesCount: 1}
解决方案
通过MongoDB聚合框架实现,完整查询语句如下:
db.Apartments.aggregate([ // 关联Users集合,拆解收藏数组并统计每个公寓的收藏次数 { $lookup: { from: "Users", pipeline: [ { $unwind: "$favorites" }, { $group: { _id: "$favorites", count: { $sum: 1 } } } ], as: "favoritesData" } }, // 将统计结果赋值给favoritesCount,未被收藏的公寓设为0 { $addFields: { favoritesCount: { $cond: { if: { $gt: [{ $size: "$favoritesData" }, 0] }, then: { $arrayElemAt: ["$favoritesData.count", 0] }, else: 0 } } } }, // 移除临时统计字段,简化返回结果 { $project: { favoritesData: 0 } } ])
语句说明
- $lookup阶段:关联Users集合,先用
$unwind拆解每个用户的收藏数组,再通过$group统计每个公寓ID的出现次数,生成临时统计数据集合。 - $addFields阶段:将统计出的收藏次数赋值给
favoritesCount字段,若公寓未被任何用户收藏,则将次数设为0。 - $project阶段:移除临时生成的
favoritesData字段,保留公寓基础信息和最终统计字段。
内容的提问来源于stack exchange,提问作者WhiteAngel
相关产品推荐
相关产品推荐

