MongoDB聚合查询中如何过滤$lookup关联的未审核餐厅评论?
解决方案
以下是修正后的MongoDB聚合查询代码,可实现仅获取关联已审核餐厅的用户评论:
const users = await db .collection('users') .aggregate([ { $lookup: { from: 'restaurants', let: { reviewRestaurantIds: '$reviews._restaurantId' }, pipeline: [ { $match: { $expr: { $and: [ { $in: ['$_id', '$$reviewRestaurantIds'] }, { $eq: ['$isApproved', true] } ] } } } ], as: 'approvedRestaurants' } }, { $project: { name: 1, surname: 1, image: 1, reviews: { $filter: { input: { $map: { input: '$reviews', as: 'review', in: { $mergeObjects: [ '$$review', { restaurant: { $arrayElemAt: [ '$approvedRestaurants', { $indexOfArray: ['$approvedRestaurants._id', '$$review._restaurantId'] } ] } } ] } } }, as: 'mappedReview', cond: { $ne: ['$$mappedReview.restaurant', null] } } } } }, { $match: { 'reviews.0': { $exists: true } } }, { $unwind: '$reviews' }, { $sort: { 'reviews.date': -1 } }, { $group: { _id: '$_id', name: { $first: '$name' }, surname: { $first: '$surname' }, image: { $first: '$image' }, reviews: { $push: '$reviews' } } }, { $limit: 12 } ]) .toArray();
关键修改说明
修正$lookup逻辑:
原写法同时使用localField/foreignField和pipeline属于MongoDB语法错误(引擎会忽略前两者),改用let传递用户的评论餐厅ID数组,在管道内通过$expr关联ID并过滤已审核餐厅,确保approvedRestaurants仅包含符合条件的数据。过滤无效评论:
先通过$map为每条评论匹配对应的已审核餐厅,再用$filter剔除匹配失败(餐厅为null)的评论,直接过滤掉指向未审核餐厅的内容。调整用户过滤时机:
将$match移到$project之后,通过'reviews.0': { $exists: true }确保只保留至少有一条有效评论的用户,避免无意义数据进入后续分组排序流程。简化餐厅信息映射:
直接将匹配到的餐厅对象赋值给restaurant字段,若前端仅需特定属性,可在$arrayElemAt内嵌套$project调整返回字段,例如:restaurant: { $arrayElemAt: [ { $project: { 'basics.name': 1, 'location.city': 1, 'location.state': 1 }, '$approvedRestaurants' }, { $indexOfArray: ['$approvedRestaurants._id', '$$review._restaurantId'] } ] }
内容的提问来源于stack exchange,提问作者Ravenwits
相关产品推荐
相关产品推荐

