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

如何在Sequelize的WHERE查询中包含关联DiscordUser的username字段?

问题:在Sequelize关联查询中添加关联模型字段的OR条件查询

我用Sequelize的findAndCountAll方法查询User模型,已经通过include关联了别名为discord_user的DiscordUser模型(关联关系是User.belongsTo(DiscordUser, {as: 'discord_user'}))。当前WHERE的Op.or里已经有email和full_name的LIKE查询,现在想加上对DiscordUser.username字段的LIKE查询,该怎么实现?

现有代码:

const users = await User.findAndCountAll({
    limit: 20,
    offset: 20 * page,
    attributes: {
        include: [[literal('`discord_user.username`'), 'username']]
    },
    order: [['email', 'ASC']],
    where: {
        [Op.or]: [
            {email: {[Op.like]: '%' + query + '%'}},
            {full_name: {[Op.like]: '%' + query + '%'}},
        ]
    },
    include: [
        {model: Licence},
        {
            model: DiscordUser,
            as: "discord_user",
        }
    ]
});

期望效果的伪代码:

where: {
    [Op.or]: [
        {email: {[Op.like]: '%' + query + '%'}},
        {full_name: {[Op.like]: '%' + query + '%'}},
        DiscordUser.username LIKE query
    ]
}

解决方案

要在主模型的Op.or条件中加入关联模型字段的查询,不能直接像主模型字段那样写,需要借助Sequelize的工具函数来指定关联表的字段。这里提供两种可靠实现方式:

方式一:使用literal直接编写SQL片段

const { Op, literal } = require('sequelize');

const users = await User.findAndCountAll({
    limit: 20,
    offset: 20 * page,
    attributes: {
        include: [[literal('`discord_user.username`'), 'username']]
    },
    order: [['email', 'ASC']],
    where: {
        [Op.or]: [
            {email: {[Op.like]: `%${query}%`}},
            {full_name: {[Op.like]: `%${query}%`}},
            // 新增关联表username的LIKE查询
            literal(`\`discord_user\`.\`username\` LIKE '%${query}%'`)
        ]
    },
    include: [
        {model: Licence},
        {
            model: DiscordUser,
            as: "discord_user",
            required: false // 保留未关联DiscordUser的用户,按需设置
        }
    ]
});

方式二:使用col+where(更安全,避免SQL注入)

如果query来自用户输入,推荐这种方式,它会自动处理参数转义:

const { Op, where, col } = require('sequelize');

const users = await User.findAndCountAll({
    limit: 20,
    offset: 20 * page,
    attributes: {
        include: [[col('discord_user.username'), 'username']] // 这里也改用col更规范
    },
    order: [['email', 'ASC']],
    where: {
        [Op.or]: [
            {email: {[Op.like]: `%${query}%`}},
            {full_name: {[Op.like]: `%${query}%`}},
            // 新增关联表字段查询
            where(col('discord_user.username'), {
                [Op.like]: `%${query}%`
            })
        ]
    },
    include: [
        {model: Licence},
        {
            model: DiscordUser,
            as: "discord_user",
            required: false
        }
    ]
});

关键注意事项

  • required: false:如果不设置,Sequelize默认会用内连接,过滤掉所有未关联DiscordUser的用户;如果业务要求用户必须关联DiscordUser,可以设为true。
  • 模板字符串%${query}%比字符串拼接更简洁易读,效果完全一致。
  • 优先使用col+where的方式处理用户输入的查询参数,防止SQL注入风险。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 20:05:30