Я пытаюсь выполнить поиск на своих моделях, я хочу, чтобы все пользователи, где либо email, firstName, либо lastName, как строка поиска, или где таблица UsersSecondaryEmails (связанная модель) содержит электронную почту, подобную этой строке.
Поскольку части инструкции OR находятся в разных таблицах, это немного сложно, и я могу найти другие ответы StackOverflow, чтобы помочь мне.
Вот мой запрос (упрощенный):
const companiesUsersParams = {
where: {
companyId: req.params.companyId,
roleId: role.id
},
include: [{
model: models.Users,
attributes: ['id', 'firstName', 'lastName', 'email'],
where: req.query.s ? {
[Op.or]: [{
firstName: {
[Op.like]: '%${req.query.s}%'
}
}, {
lastName: {
[Op.like]: '%${req.query.s}%'
}
}, {
email: {
[Op.like]: '%${req.query.s}%'
}
}, {
'$usersSecondaryEmails.email$': {
[Op.like]: '%${req.query.s}%'
}
}]
} : null,
include: [{
model: models.UsersSecondaryEmails,
attributes: ['id', 'email'],
as: 'usersSecondaryEmails'
}]
}]
}
Когда req.query.s
не определен, запрос выполняется как ожидалось (нет инструкции OR), поэтому я знаю, что это не проблема с моими ассоциациями.
Когда я запускаю этот запрос с req.query.s
, я получаю
Неизвестный столбец 'usersSecondaryEmails.email' в 'on clause'
И вот генерируется SQL (отформатированный как можно лучше):
SELECT 'companiesUsers'.'id',
'companiesUsers'.'company_id' AS 'companyId',
'companiesUsers'.'user_id' AS 'userId',
'companiesUsers'.'role_id' AS 'roleId',
'companiesUsers'.'created_at' AS 'createdAt',
'companiesUsers'.'updated_at' AS'updatedAt',
'user'.'id' AS 'user.id',
'user'.'first_name' AS 'user.firstName',
'user'.'last_name' AS 'user.lastName',
'user'.'email' AS 'user.email',
'user->usersSecondaryEmails'.'id' AS 'user.usersSecondaryEmails.id',
'user->usersSecondaryEmails'.'email' AS
'user.usersSecondaryEmails.email'
FROM 'CompaniesUsers' AS 'companiesUsers'
INNER JOIN 'Users' AS 'user'
ON 'companiesUsers'.'user_id' = 'user'.'id' AND
('user'.'first_name' LIKE '%bob%' OR
'user'.'last_name' LIKE '%bob%' OR
'user'.'email' LIKE '%bob%' OR
'usersSecondaryEmails'.'email' LIKE '%bob%')
LEFT OUTER JOIN 'UsersSecondaryEmails' AS 'user->usersSecondaryEmails'
ON 'user'.'id' = 'user->usersSecondaryEmails'.'user_id'
WHERE 'companiesUsers'.'company_id' = '1'
AND 'companiesUsers'.'role_id' = 20;
Любые любые советы или ссылки на документацию по операторам с несколькими таблицами OR в Sequelize были бы замечательными (я не мог найти ничего такого в документации).
Я не уверен, как изменить код Sequelize для companiesUsersParams
, но ваш окончательный запрос должен выглядеть ниже, чтобы получить желаемый результат. Это может помочь вам переписать код Sequelize.
usersSecondaryEmails.email LIKE '%bob%'
в состояние подключения UsersSecondaryEmailsВ предложении where проверьте условие (по крайней мере, одна строка должна существовать в любой таблице пользователя или usersSecondaryEmails для userid)
SELECT companiesUsers.id, companiesUsers.company_id AS companyId, companiesUsers.user_id AS userId, companiesUsers.role_id AS roleId, companiesUsers.created_at AS createdAt, companiesUsers.updated_at ASupdatedAt, user.id AS user.id, user.first_name AS user.firstName, user.last_name AS user.lastName, user.email AS user.email, user->usersSecondaryEmails.id AS user.usersSecondaryEmails.id, user->usersSecondaryEmails.email AS user.usersSecondaryEmails.email FROM CompaniesUsers AS companiesUsers LEFT OUTER JOIN Users AS user ---- #1 ON companiesUsers.user_id = user.id AND (user.first_name LIKE '%bob%' OR user.last_name LIKE '%bob%' OR user.email LIKE '%bob%' OR) LEFT OUTER JOIN UsersSecondaryEmails AS user->usersSecondaryEmails ON companiesUsers.user_id = user->usersSecondaryEmails.user_id AND user->usersSecondaryEmails.email LIKE '%bob%' ---- #2 WHERE companiesUsers.company_id = '1' AND companiesUsers.role_id = 20 AND (user.email is Not null OR user->usersSecondaryEmails.user_id is Not Null); ---- #3
usersSecondaryEmails.email LIKE '%bob%'