Mysql Sequelize:如何使用多个操作符创建带有排除子句的对象获取
我正在使用MySQL的NodeJS/Express/Angular7应用程序中使用Sequelize 5 我有一个图像表,它通过一个联接表与一个关键字表具有双向关系 我想找到在ID数组[kewordsAnd]中包含关键字ID的所有图像,排除在要排除[keywordsNot]的数组中包含关键字ID的图像 现时的守则如下:Mysql Sequelize:如何使用多个操作符创建带有排除子句的对象获取,mysql,node.js,angular,express,sequelize.js,Mysql,Node.js,Angular,Express,Sequelize.js,我正在使用MySQL的NodeJS/Express/Angular7应用程序中使用Sequelize 5 我有一个图像表,它通过一个联接表与一个关键字表具有双向关系 我想找到在ID数组[kewordsAnd]中包含关键字ID的所有图像,排除在要排除[keywordsNot]的数组中包含关键字ID的图像 现时的守则如下: Image.findAll({ include: [ { model: Keywords, as: 'Keywords', attributes: [
Image.findAll({
include: [ {
model: Keywords,
as: 'Keywords',
attributes: ['id', 'name'],
where: {
id: {
[Op.and]: [
{ [Op.in]: keywordsAnd },
{ [Op.notIn]: keywordsNot }
]
}
}
} ]
});
这将正确地获取在关键字和数组中具有ID的所有图像,但关键字snot数组将被完全忽略
这是为可读性而添加的生成的SQL换行符
const objectsAnd: [ 430 ]
const objectsNot: [ 779 ]
Executing (default):
SELECT `image`.`id`, `image`.`status`, `image`.`image_type`, `image`.`embed`,
`image`.`raw_path`, `image`.`thumb_path`, `image`.`detail_path`, `image`.`story_title`,
`image`.`image_title`, `image`.`original_filename`, `image`.`description`,
`image`.`geo_info`, `image`.`year_taken`, `image`.`credit_info`,
`image`.`width`, `image`.`height`, `image`.`format`, `image`.`duration`,
`image`.`created_at`
AS `createdAt`, `image`.`updated_at` AS `updatedAt`, `keywords`.`id` AS `keywords.id`,
`keywords`.`name` AS `keywords.name`, `keywords`.`created_at` AS `keywords.createdAt`,
`keywords`.`updated_at` AS `keywords.updatedAt`, `keywords->image_keywords`.`id` AS
`keywords.image_keywords.id`, `keywords->image_keywords`.`image_id` AS
`keywords.image_keywords.image_id`, `keywords->image_keywords`.`keyword_id` AS
`keywords.image_keywords.keyword_id`, `keywords->image_keywords`.`created_at` AS
`keywords.image_keywords.createdAt`, `keywords->image_keywords`.`updated_at` AS
`keywords.image_keywords.updatedAt`
FROM `image` AS `image` INNER JOIN ( `image_keywords` AS `keywords->image_keywords`
INNER JOIN `keywords` AS `keywords`
ON `keywords`.`id` = `keywords->image_keywords`.`keyword_id`)
ON `image`.`id` = `keywords->image_keywords`.`image_id`
AND (`keywords`.`id` IN (430) AND `keywords`.`id` NOT IN (779));
我不清楚这是否与我如何构造查询有关,或者是一个bug,或者是我对该如何工作的完全误解,但我真的希望得到一些指导。鉴于下面的示例数据,您是否只希望得到图1而不是图2的结果
image id keyword id
1 430
2 430
2 709
如果是这样,那么问题在于您的查询。您需要选择具有关键字ID709的图像id,并将其用作NOT IN语句的基础 为什么不使用之前处理过的一个数组来删除'outClause'中的'Incluse'中的ID呢?查询的性能会更好,不是吗?有些图像只包含想要的关键字,有些图像包含想要的关键字和不想要的关键字,我正在尝试获取前者并排除后者。我不知道重叠在哪里,直到我用限定符查询图像。这正是我试图实现的-是的。我明白你的意思,我想,但我不知道该如何组织。我是否需要查询两次,首先获取排除关键字的图像ID,然后将该数组传递到第二个查询中?我可以在一个嵌套查询中完成吗?我对Sequelize语法是全新的,所以我不完全清楚构造它的最佳方法。在一个过程中完成这项工作需要子查询,Sequelize并不真正支持子查询。您可以使用模拟子查询,但在这种情况下,IMHO会很尴尬。我很想嵌入一个文字,比如:id:{Op.notIn:sequelize.literal'SELECT image\u id FROM image\u keywords internal JOIN keywords ON image\u keywords.keywords\u id=keywords.id WHERE keywords\u id IN'},我正在使用Node/Express-如果我链接承诺并获取要排除的关键字的图像,并获取这些图像ID的数组,然后将该数组传递到我想要的图像的第二次获取中,并使用初始数组作为Op.notIn参数,这会有意义吗?这也应该起作用。但是,性能可能会下降2次服务器访问,特别是当您的排除图像列表往往非常大时。