MongoDB如何根据gameType参数返回指定格式统计数据?
MongoDB 查询语句实现游戏统计汇总逻辑
样例文档结构
{ "userId": 1, "totalGames": 10, "winStats": 4, "lostStats": 6, "g1Stats": { "totalGames": 4, "winStats": 1, "lostStats": 3 }, "g2Stats": { "totalGames": 5, "winStats": 2, "lostStats": 3 }, "g3Stats": { "totalGames": 1, "winStats": 1, "lostStats": 0 } }
返回数据格式要求
返回结果必须固定为以下结构,便于后续排序操作:
{ "userId": 1, "totalGames": 9, "winStats": 3, "lostStats": 6 }
逻辑规则
- 若传入
gameType参数为["g1", "g2"]这类非空数组,需汇总对应g1Stats、g2Stats中的totalGames、winStats、lostStats字段值 - 若传入
gameType参数为空数组[],直接返回文档顶层的totalGames、winStats、lostStats字段值
实现查询语句
使用MongoDB聚合管道实现上述逻辑,可根据传入的gameType参数动态处理:
// 示例:定义传入的gameType参数,可替换为实际业务中的变量 const gameType = ["g1", "g2"]; // 或 [] db.collection.aggregate([ { $addFields: { // 将传入的gameType参数注入聚合管道 targetGameTypes: gameType } }, { $project: { userId: 1, totalGames: { $cond: { if: { $eq: ["$targetGameTypes", []] }, then: "$totalGames", else: { $sum: { $map: { input: "$targetGameTypes", as: "type", in: { $getField: { field: "totalGames", input: { $getField: { field: { $concat: ["$$type", "Stats"] }, input: "$$ROOT" } } } } } } } } }, winStats: { $cond: { if: { $eq: ["$targetGameTypes", []] }, then: "$winStats", else: { $sum: { $map: { input: "$targetGameTypes", as: "type", in: { $getField: { field: "winStats", input: { $getField: { field: { $concat: ["$$type", "Stats"] }, input: "$$ROOT" } } } } } } } } }, lostStats: { $cond: { if: { $eq: ["$targetGameTypes", []] }, then: "$lostStats", else: { $sum: { $map: { input: "$targetGameTypes", as: "type", in: { $getField: { field: "lostStats", input: { $getField: { field: { $concat: ["$$type", "Stats"] }, input: "$$ROOT" } } } } } } } } } } } ])
语句说明
- 通过
$addFields将传入的gameType参数注入到聚合管道中,方便后续判断 - 使用
$cond判断targetGameTypes是否为空数组:- 为空时直接取文档顶层的统计字段
- 非空时,通过
$map遍历数组中的游戏类型,拼接成g1Stats这类字段名,再用$getField获取对应嵌套字段的统计值,最后用$sum汇总求和
$project阶段固定返回指定字段,保证输出格式符合要求
内容的提问来源于stack exchange,提问作者Vishal Tyagi
相关产品推荐
相关产品推荐

