You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在discord.js中实现quickmongo经济机器人的服务器专属排行榜

优化方案

原代码崩溃核心原因有两个:一是大服下发起了和成员数对等的海量并发数据库查询,数据库IO和进程内存直接被打满;二是无差别遍历全服成员做无效查询,大量零余额/不在经济系统内的用户占用了不必要的资源。
优化思路是从数据库侧批量拉取数据,再做服务器成员归属过滤,完全不需要遍历全服务器成员缓存,实现代码如下:

// 1. 一次性批量拉取所有有余额的用户数据,仅1次数据库请求
const allBalanceData = await db.startsWith("mon_");
// (可选)如果未开启成员缓存,先执行一次全量成员拉取:await message.guild.members.fetch()
// 2. 预生成当前服务器所有成员ID的Set,判断存在性的时间复杂度为O(1)
const guildMemberIds = new Set(message.guild.members.cache.map(m => m.id));
// 3. 过滤出属于当前服务器、且余额大于0的用户
const serverRichList = allBalanceData
  .filter(item => {
    const userId = item.key.split("_")[1];
    return guildMemberIds.has(userId) && item.data > 0;
  })
  .map(async item => {
    const userId = item.key.split("_")[1];
    const nick = await db.fetch(`nick_${userId}`) || message.guild.members.cache.get(userId).user.tag;
    return {
      data: item.data,
      ID: nick
    };
  });
// 等待所有昵称查询完成,并发量仅为榜单长度级,资源占用极低
const processedList = await Promise.all(serverRichList);
// 4. 排序取前5
const sortedList = processedList.sort((a, b) => b.data - a.data).slice(0, 5);
if (sortedList.length < 1) return message.reply('No rich people here -_-');
// 5. 拼接输出文本
let final = "";
sortedList.forEach((item, index) => {
  let medal = '🔹️';
  if (index === 0) medal = '🥇';
  else if (index === 1) medal = '🥈';
  else if (index === 2) medal = '🥉';
  final += `${medal} **${item.data.toLocaleString()}** - ${item.ID}\n`;
});
// 后续发送final的逻辑自行补充

优化效果说明

  • 数据库请求量从原来的2*服务器成员数降低到1 + 榜单长度,大服场景下性能提升上千倍
  • 完全不需要遍历全服务器成员,只处理有余额的有效用户,内存占用降低90%以上
  • 修复了原代码的拼写错误xy.lenght、数组遍历索引取值错误的问题

内容的提问来源于stack exchange,提问作者GentleScreamer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.12 11:33:03