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

Node.js v8.9.4中mysql2模块消息队列查询优化求助

实现符合多条件的消息队列查询(Node.js v8.9.4 + mysql2)

我帮你把这个多条件的消息查询逻辑完整实现出来,适配你使用的Node.js v8.9.4和mysql2模块,同时满足你列出的所有筛选条件:

核心筛选条件回顾

  • 消息本身的status等于0
  • 对应botId的status=1消息数量小于设定的最大值(这里是10)
  • wait表中,botId+chatId组合以及单独botId对应的retry_after都小于当前时间戳
  • 不存在相同chatId且status=1的活跃消息

完整实现代码

const mysql = require('mysql2/promise');
const Util = require('./your-util-module'); // 替换为你的Util模块路径

class MessageQueueService {
  static async Find(activeMessageIds, maxActiveMsgPerBot) {
    let params = [maxActiveMsgPerBot];
    let filterActiveMessageIds = '';
    const currentTimestamp = Util.GetTimeStamp();

    // 处理传入的活跃消息ID列表,排除已在处理的消息
    if (activeMessageIds && Array.isArray(activeMessageIds) && activeMessageIds.length > 0) {
      filterActiveMessageIds = ' AND m.id NOT IN (?)';
      params.push(activeMessageIds);
    }

    // 构造满足所有条件的SQL查询语句
    const querySql = `
      SELECT m.*
      FROM messages m
      -- 条件1:筛选待处理状态的消息
      WHERE m.status = 0
      -- 条件4:确保当前对话没有活跃中的消息
      AND NOT EXISTS (
        SELECT 1 
        FROM messages active_msg
        WHERE active_msg.chatId = m.chatId 
          AND active_msg.status = 1
      )
      -- 条件2:限制单bot的活跃消息数不超过最大值
      AND (
        SELECT COUNT(*) 
        FROM messages bot_active_msg
        WHERE bot_active_msg.botId = m.botId 
          AND bot_active_msg.status = 1
      ) < ?
      -- 条件3:检查wait表中bot+chat的重试时间已过期
      AND NOT EXISTS (
        SELECT 1 
        FROM wait w_chat
        WHERE w_chat.botId = m.botId 
          AND w_chat.chatId = m.chatId 
          AND w_chat.retry_after >= ?
      )
      -- 条件3补充:检查wait表中单独bot的重试时间已过期
      AND NOT EXISTS (
        SELECT 1 
        FROM wait w_bot
        WHERE w_bot.botId = m.botId 
          AND w_bot.chatId IS NULL 
          AND w_bot.retry_after >= ?
      )
      ${filterActiveMessageIds}
      -- 按创建时间排序,优先处理更早的消息
      ORDER BY m.created_at ASC
      LIMIT 1; -- 按需调整返回数量,这里取第一条符合条件的消息
    `;

    // 将时间戳参数加入参数列表
    params.push(currentTimestamp, currentTimestamp);

    try {
      // 初始化数据库连接(建议用连接池,这里示例用单次连接)
      const connection = await mysql.createConnection({
        host: '你的数据库地址',
        user: '数据库用户名',
        password: '数据库密码',
        database: '数据库名称'
      });

      // 执行查询
      const [resultRows] = await connection.execute(querySql, params);
      await connection.end();

      // 返回结果,没有找到则返回null
      return resultRows.length > 0 ? resultRows[0] : null;
    } catch (error) {
      console.error('查询消息队列时出错:', error);
      throw error; // 将错误抛出给上层调用者处理
    }
  }
}

module.exports = MessageQueueService;

代码关键点说明

  1. 参数绑定与SQL安全:使用mysql2的参数占位符?来避免SQL注入,参数顺序严格对应占位符位置
  2. Node.js v8.9.4兼容:使用mysql2/promise来支持async/await语法(v8.9.4已经稳定支持async/await)
  3. 条件逻辑实现:
    • 用NOT EXISTS子查询处理“不存在某类数据”的判断,比JOIN更直观高效
    • 子查询统计bot的活跃消息数,确保不超过上限
    • 分别检查wait表中两种重试时间的条件,确保都满足过期要求
  4. 灵活性:支持传入activeMessageIds排除已在处理的消息,可通过调整LIMIT控制返回的消息数量

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:22:28