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

如何用Mongoose的.find()实现Discord机器人用户重复添加校验?

问题解决思路

核心问题分析

  1. 异步操作处理错误:Mongoose的find方法返回的是Query对象,不是布尔值,直接用!ModeratorSchema.find(...)判断永远为true,导致每次都执行创建操作。而MongoDB因为user_id的唯一约束会拒绝重复插入,但你的代码没有捕获这个错误,所以Discord仍会返回“添加成功”的提示。
  2. 校验代码语法错误:你之前的校验代码把回调函数写在了括号外,语法错误导致代码不执行,自然没有输出;另外find返回的是数组,即使无数据也是空数组[],用if (data)判断会认为空数组为真,逻辑错误。

修正后的代码实现

方法1:使用Async/Await(推荐)

将命令处理函数改为异步函数,先查询用户是否存在,再执行后续逻辑:

// 确保你的命令处理函数是async的
async function handleModeratorAdd(interaction) {
    const target = interaction.options.getUser('target'); // 假设你通过此获取目标用户
    const permissionType = interaction.options.getInteger("type");
    const log_channel = "你的日志频道ID";

    try {
        // 查询数据库中是否存在该用户
        const existingModerator = await ModeratorSchema.findOne({ user_id: target.id });
        if (existingModerator) {
            return interaction.reply({
                content: "User is already a system moderator.",
                ephemeral: true
            });
        }

        // 创建新管理员记录
        await ModeratorSchema.create({
            username: target.username,
            user_id: target.id,
            type: permissionType
        });

        // 发送成功反馈与日志
        await interaction.reply({
            content: `Added \`${target} (${target.id})\` as a system moderator with permission level ${permissionType}`,
            ephemeral: true
        });

        await client.channels.cache.get(log_channel).send({
            content: `\`${target} (${target.id})\` was added as a system moderator by \`${interaction.user.username} (${interaction.user.id})\` with permission level \`${permissionType}\`.`
        });
    } catch (err) {
        // 捕获MongoDB唯一约束错误
        if (err.code === 11000) {
            return interaction.reply({
                content: "User is already a system moderator.",
                ephemeral: true
            });
        }
        // 处理其他异常
        console.error("Error adding moderator:", err);
        return interaction.reply({
            content: "An error occurred while adding the moderator.",
            ephemeral: true
        });
    }
}

方法2:使用回调函数(兼容旧代码)

如果更习惯回调风格,修正语法与逻辑:

const target = interaction.options.getUser('target');
const permissionType = interaction.options.getInteger("type");
const log_channel = "你的日志频道ID";

ModeratorSchema.findOne({ user_id: target.id }, (err, existingModerator) => {
    if (err) {
        console.error("Error checking moderator:", err);
        return interaction.reply({
            content: "An error occurred while checking moderator status.",
            ephemeral: true
        });
    }

    if (existingModerator) {
        return interaction.reply({
            content: "User is already a system moderator.",
            ephemeral: true
        });
    }

    ModeratorSchema.create({
        username: target.username,
        user_id: target.id,
        type: permissionType
    }, (createErr) => {
        if (createErr) {
            if (createErr.code === 11000) {
                return interaction.reply({
                    content: "User is already a system moderator.",
                    ephemeral: true
                });
            }
            console.error("Error creating moderator:", createErr);
            return interaction.reply({
                content: "An error occurred while adding the moderator.",
                ephemeral: true
            });
        }

        interaction.reply({
            content: `Added \`${target} (${target.id})\` as a system moderator with permission level ${permissionType}`,
            ephemeral: true
        });

        client.channels.cache.get(log_channel).send({
            content: `\`${target} (${target.id})\` was added as a system moderator by \`${interaction.user.username} (${interaction.user.id})\` with permission level \`${permissionType}\`.`
        });
    });
});

关键注意事项

  • 使用findOne而非find:find返回数组,即使无数据也是空数组;findOne找不到数据时返回null,判断更直接。
  • 捕获唯一约束错误:即使提前查询,也可能因并发请求出现竞态条件,必须捕获MongoDB的11000错误码,确保反馈准确。
  • 等待异步操作完成:无论是await还是回调,都要确保数据库操作完成后再执行Discord回复,避免逻辑混乱。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 22:33:19