MongoDB分组聚合:如何根据最值获取对应文档或名称?
解决方案
要同时获取获赞最多(likes最大值)和获踩最多(dislikes最大值)的用户名称或完整文档,你可以通过以下几种MongoDB聚合管道实现:
方案一:先获取全局最大值,再关联原集合查询对应用户
这个方法逻辑直观,先通过$group计算出全局的最大点赞数和踩数,再用$lookup关联原集合获取对应的用户文档:
const result = await regionModel.aggregate([ // 第一步:计算全局最大likes和dislikes { $group: { _id: null, maxLikes: { $max: "$likes" }, maxDislikes: { $max: "$dislikes" } } }, // 第二步:关联原集合,查找获赞最多的用户(替换from的值为你的集合名称) { $lookup: { from: "regionModel", localField: "maxLikes", foreignField: "likes", as: "mostLikedUsers" } }, // 第三步:关联原集合,查找获踩最多的用户 { $lookup: { from: "regionModel", localField: "maxDislikes", foreignField: "dislikes", as: "mostDislikedUsers" } }, // 第四步:调整输出格式,取第一个匹配的用户(处理多个用户同最大值的情况) { $project: { _id: 0, maxLikes: 1, // 若只需名称,替换为mostLikedName: { $arrayElemAt: ["$mostLikedUsers.name", 0] } mostLikedUser: { $arrayElemAt: ["$mostLikedUsers", 0] }, maxDislikes: 1, // 若只需名称,替换为mostDislikedName: { $arrayElemAt: ["$mostDislikedUsers.name", 0] } mostDislikedUser: { $arrayElemAt: ["$mostDislikedUsers", 0] } } } ])
方案二:使用窗口函数计算全局最大值,再筛选对应用户
通过$setWindowFields计算全局的最大点赞/踩数,再筛选出符合条件的用户文档:
const result = await regionModel.aggregate([ { $match: { likes: { $gt: 0 } } }, // 计算全局范围内的最大likes和dislikes { $setWindowFields: { partitionBy: null, output: { globalMaxLikes: { $max: "$likes" }, globalMaxDislikes: { $max: "$dislikes" } } } }, // 筛选出获赞最多或获踩最多的用户 { $match: { $or: [ { likes: { $eq: "$globalMaxLikes" } }, { dislikes: { $eq: "$globalMaxDislikes" } } ] } }, // 分组整理结果 { $group: { _id: null, maxLikes: { $first: "$globalMaxLikes" }, maxDislikes: { $first: "$globalMaxDislikes" }, mostLikedUsers: { $push: { $cond: [{ $eq: ["$likes", "$globalMaxLikes"] }, "$$ROOT", null] } }, mostDislikedUsers: { $push: { $cond: [{ $eq: ["$dislikes", "$globalMaxDislikes"] }, "$$ROOT", null] } } } }, // 过滤无效值并输出最终结果 { $project: { _id: 0, maxLikes: 1, mostLikedUser: { $arrayElemAt: [{ $filter: { input: "$mostLikedUsers", cond: { $ne: ["$$this", null] } } }, 0] }, maxDislikes: 1, mostDislikedUser: { $arrayElemAt: [{ $filter: { input: "$mostDislikedUsers", cond: { $ne: ["$$this", null] } } }, 0] } } } ])
输出示例
如果选择获取完整文档,最终输出类似:
{ "maxLikes": 60, "mostLikedUser": { "_id": 2, "name": "Ant", "joined": ISODate("2012-07-02T00:00:00Z"), "likes": 60, "dislikes": 2 }, "maxDislikes": 9, "mostDislikedUser": { "_id": 0, "name": "jane", "joined": ISODate("2011-03-02T00:00:00Z"), "likes": 30, "dislikes": 9 } }
若只需用户名称,修改$project中的字段即可得到你期望的格式。
内容的提问来源于stack exchange,提问作者Zillur Rahman
相关产品推荐
相关产品推荐

