单条MongoDB按多值分组查询返回多列表获取球员各赛季队友方法
解决方案
你可以通过MongoDB聚合管道实现单次查询返回所有分组的队友结果,具体实现步骤如下:
步骤1:平铺目标队年组合
先把原始球员的效力队伍数据,平铺为18个(球队名, 年份)的匹配单元:
// 示例球员数据 const player = { _id: '/players/c/cruzne02.shtml', name: 'Nelson Cruz', teams: [ { name: 'MIL', years: [ 2005 ] }, { name: 'TEX', years: [ 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 ] }, { name: 'BAL', years: [ 2014 ] }, { name: 'SEA', years: [ 2015, 2016, 2017, 2018 ] }, { name: 'MIN', years: [ 2019, 2020, 2021 ] }, { name: 'TBR', years: [ 2021 ] } ] } // 平铺为18个匹配条件单元 const matchConditions = player.teams.flatMap(team => team.years.map(year => ({ teamName: team.name, targetYear: year, elemMatch: { name: team.name, years: year } })) )
步骤2:构造聚合查询语句
直接调用一次聚合接口即可返回所有分组结果:
const result = await db.collection.aggregate([ // 第一阶段:过滤出所有符合任意队年组合的球员,排除球员本人 { $match: { _id: { $ne: player._id }, $or: matchConditions.map(item => ({ teams: { $elemMatch: item.elemMatch } })) } }, // 第二阶段:给每个球员标记他属于哪些队年分组 { $addFields: { belongGroups: { $filter: { input: matchConditions, cond: { $gt: [ { $size: { $filter: { input: '$teams', cond: { $and: [ { $eq: ['$$this.name', '$$item.teamName'] }, { $in: ['$$item.targetYear', '$$this.years'] } ] } } } }, 0 ] } } } } }, // 第三阶段:把属于多个分组的球员拆分为单条记录 { $unwind: '$belongGroups' }, // 第四阶段:按队年组合分组,聚合所有对应队友 { $group: { _id: { team: '$belongGroups.teamName', year: '$belongGroups.targetYear' }, teammates: { $push: '$$ROOT' } } } ]).toArray()
结果说明
返回的result数组共18个元素,每个元素对应一个队年组合:
_id字段存储对应的球队名和年份teammates数组存储该队该年所有和Nelson Cruz同队的球员
你也可以根据需求调整$group阶段的逻辑,仅返回队友的姓名、ID等必要字段减少数据传输。
内容的提问来源于stack exchange,提问作者laneherby
相关产品推荐
相关产品推荐

