Sequelize: как использовать несколько операторов для создания выборки объектов с предложением исключения - PullRequest
0 голосов
/ 08 мая 2019

Я использую Sequelize 5 в приложении NodeJS / Express / Angular7 с использованием MySQL.

У меня есть таблица изображений с двунаправленным отношением hasMany к таблице ключевых слов через объединяющую таблицу.

Я хочу найти все изображения, которые содержат идентификаторы ключевых слов, в массиве идентификаторов [ kewordsAnd ], за исключением изображений, которые имеют идентификаторы ключевых слов в массиве, чтобы исключить [ KeywordsNot ].

Код сейчас выглядит следующим образом:

Image.findAll({
  include: [ {
    model: Keywords,
    as: 'Keywords',
    attributes: ['id', 'name'],
    where: {
      id: {
        [Op.and]: [
          { [Op.in]: keywordsAnd },
          { [Op.notIn]: keywordsNot }
        ]
      }
    }
  } ]
});

При этом корректно извлекаются все изображения, имеющие идентификаторы в массиве keywordAnd , но массив wordsNot полностью игнорируется.

Это сгенерированный 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));

Мне неясно, является ли это проблемой с тем, как я структурирую запрос, или ошибкой, или полным недоразумением с моей стороны относительно того, как это должно работать, но я действительно надеюсь на какое-то руководство.

1 Ответ

1 голос
/ 09 мая 2019

Учитывая приведенные ниже примеры данных, ожидаете ли вы результатов ТОЛЬКО изображение 1 (а НЕ изображение 2)?

image id    keyword id
1           430
2           430
2           709

Если так, то проблема в вашем запросе. Вам нужно будет выбрать идентификатор изображения s с ключевым словом id 709 и использовать его в качестве основы для вашего оператора NOT IN.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...