MongoDB嵌套JSON集合查询:无需指定固定teamId获取所有球员ID和进球数
MongoDB 无需硬编码teamId查询所有球员playerId及进球数据方案
普通find查询的投影无法遍历teamsData下的动态teamId键,需要使用聚合框架处理动态字段:
// MongoDB Shell 语法 db.matches.aggregate([ // 1. 将动态键的teamsData对象转为数组,每个元素为{k: teamId, v: 球队数据} { $addFields: { teams: { $objectToArray: "$teamsData" } } }, // 2. 拆分数组得到单条球队记录 { $unwind: "$teams" }, // 3. 合并首发+替补的所有球员数据,仅查首发的话可以去掉$concatArrays直接取$teams.v.formation.lineup { $addFields: { allPlayers: { $concatArrays: [ "$teams.v.formation.lineup", "$teams.v.formation.bench" ] }, teamId: "$teams.v.teamId" } }, // 4. 拆分数组得到单条球员记录 { $unwind: "$allPlayers" }, // 5. 仅保留需要的字段 { $project: { teamId: 1, playerId: "$allPlayers.playerId", goals: "$allPlayers.goals" // 不需要_id的话可以加 _id: 0 隐藏 } } ])
适配你原有Pymongo写法的代码如下:
result = list(db.matches.aggregate([ { "$addFields": { "teams": {"$objectToArray": "$teamsData"} } }, {"$unwind": "$teams"}, { "$addFields": { "allPlayers": {"$concatArrays": ["$teams.v.formation.lineup", "$teams.v.formation.bench"]}, "teamId": "$teams.v.teamId" } }, {"$unwind": "$allPlayers"}, { "$project": { "teamId": 1, "playerId": "$allPlayers.playerId", "goals": "$allPlayers.goals" } } ]))
返回结果说明
每条结果对应1名球员,包含所属球队ID、球员ID和进球数据,示例如下:
[ {"_id": ObjectId("615e9b8d17fa084f2e8d4b83"), "teamId": 12274, "playerId": 101652, "goals": "null"}, {"_id": ObjectId("615e9b8d17fa084f2e8d4b83"), "teamId": 9598, "playerId": 69616, "goals": "1"}, ... ]
提示:如果只需要查询首发球员数据,将
$concatArrays部分替换为"$teams.v.formation.lineup"即可,本方案兼容MongoDB 3.4.4及以上版本。
内容的提问来源于stack exchange,提问作者Luiz Felipe Freitas
相关产品推荐
相关产品推荐

