Node.js开发基于奖杯数的matchmake匹配功能触发无限循环问题求助
问题原因
- 核心问题1:聚合查询的
$match阶段没有排除当前用户自身,若符合奖杯数范围的用户只有当前用户一人,$sample每次都只能返回当前用户,触发if判断后会递归调用自身,直接陷入无限递归死循环。 - 核心问题2:递归逻辑没有设置终止阈值,就算符合范围的存在其他用户,极端情况下连续多次随机到自身也会导致递归层数过高,最终爆栈或者无限运行。
- 隐藏问题:没有处理聚合查询返回空结果的场景,当没有符合奖杯范围的用户时,访问
userMatched[0].userID会直接抛出异常。
修复方案
直接修改聚合查询逻辑,从数据源层面排除当前用户,完全不需要递归判断,修复后代码如下:
const UserProfile = require("../schemas/userProfile") async function matchmake(user, message) { // 获取当前用户奖杯数 const UserProfileDetails = await UserProfile.findOne({ userID: user.id }); const userTrophies = UserProfileDetails.trophies; // 聚合查询直接排除当前用户,从根源避免抽到自己 const userMatched = await UserProfile.aggregate([ { $match: { userID: { $ne: user.id }, // 新增过滤规则:排除当前用户自身 trophies: { $gte: userTrophies - 10, $lte: userTrophies + 10 } } }, { $sample: { size: 1 } } ]); // 处理无匹配用户的边界情况,可根据业务需求调整返回值或者抛出业务异常 if (!userMatched.length) { return null; } return userMatched[0].userID; } module.exports = { matchmake }
- 如果业务需要支持无匹配时自动扩大奖杯范围重试,可以在判断无结果时逐步放宽
trophies的上下限阈值,同时设置最大重试次数即可,避免无限重试。
内容的提问来源于stack exchange,提问作者abc
相关产品推荐
相关产品推荐

