Sequelize Верхний уровень, где с загруженными моделями создается подзапрос - PullRequest
0 голосов
/ 13 сентября 2018

Я сталкиваюсь с проблемой, когда Sequelize создает подзапрос первичной модели, а затем соединяет включения с этим подзапросом, а не напрямую с таблицей первичной модели. Условия запроса для include (s) заканчиваются в предложении WHERE подзапроса, что делает его недействительным. Я сократил имена, пытаясь сохранить этот компакт, надеюсь, не теряя никакой соответствующей информации.

Окружающая среда: Узлы: 6.11.3 Sequelize: 3.23.6 => Обновлено до 4.38.1 и проблема остается MySql: 5,7,23

Модели с фрагментами кода:

I.model:
   models.I.hasMany(models.II);
   models.I.belongsTo(models.CJ);
   models.I.belongsTo(models.CJS);
II.model:
   models.II.belongsTo(models.I);
CJ.model:
   models.CJ.hasMany(models.I);
   models.CJ.hasMany(models.CJS);
CJS.model:
    models.CJS.hasMany(models.I);

Определение запроса кода:

let where = { cId: '2',
iAmt: { '$gt': 0 },
'$or': 
 [ { '$CJ.a1$': {$like: '%246%'}} },
   { '$CJ.a2$': {$like: '%246%'} },
   { '$I.cPN$': {$like: '%246%'} } 
 ] };

 let query = {
   where: where,
   order: orderBy,
   distinct: true,
   offset: offset,
   limit: limit,
   include: [
   {
    model: CJ, 
    as: 'CJ',
    required: false
  }, {
    model: CJS, 
    as: 'CJS',
    required: false
  }, {
    model: II,
    as: 'IIs',
    required: false
  }
  ]
  };

  I.findAll(query)

Создает SQL следующим образом:

SELECT `I`.*, `CJ`.`_id` AS `CJ._id`, `CJS`.`_id` AS `CJS._id`, `IIs`.`_id` AS `IIs._id`
FROM (SELECT `I`.`_id`, `I`.`CJId`, `I`.`CJSId`, `I`.`CId` 
  FROM `Is` AS `I` 
 WHERE `I`.`CId` = '2' AND 
       `I`.`iA` > 0 AND 
     (`CJ`.`a1` LIKE '%246%' OR 
      `CJ`.`a2` LIKE '%246%' OR 
      `I`.`cPN` LIKE '%246%'
     ) 
     ORDER BY `I`.`iNum` DESC LIMIT 0, 10) AS `I` 
     LEFT OUTER JOIN `CJs` AS `CJ` ON `I`.`CJId` = `CJ`.`_id` 
     LEFT OUTER JOIN `CJSs` AS `CJS` ON `I`.`CJSId` = `CJS`.`_id` 
     LEFT OUTER JOIN `IIs` AS `IIs` ON `I`.`_id` = `IIs`.`IId` 
     ORDER BY `I`.`iNum` DESC;

Я ожидал что-то вроде этого:

SELECT `I`.*, `CJ`.`_id` AS `CJ._id`, `CJS`.`_id` AS `CJS._id`, `IIs`.`_id` AS `IIs._id`
  FROM `Is` AS `I` 
     LEFT OUTER JOIN `CJs` AS `CJ` ON `I`.`CJId` = `CJ`.`_id` 
     LEFT OUTER JOIN `CJSs` AS `CJS` ON `I`.`CJSId` = `CJS`.`_id` 
     LEFT OUTER JOIN `IIs` AS `IIs` ON `I`.`_id` = `IIs`.`IId` 

WHERE `I`.`CId` = '2' AND 
       `I`.`iA` > 0 AND 
     (`CJ`.`a1` LIKE '%246%' OR 
      `CJ`.`a2` LIKE '%246%' OR 
      `I`.`cPN` LIKE '%246%'
) 
ORDER BY `I`.`iNum` DESC LIMIT 0, 10

Если я удаляю модель II из включения, она работает и перемещает ГДЕ на верхний уровень. Я допускаю, что структура запроса здесь не проста: I является потомком CJ и CJS , который, в свою очередь, является потомком CJ . И тогда II ребенок I . Что мне здесь не хватает?

Добро пожаловать Буллера или чьих-либо центов!

1 Ответ

0 голосов
/ 12 декабря 2018

что произошло здесь, потому что вы также используете order и limit вместе с готовой ассоциацией загрузки см. Проблему

чтобы все заработало, есть маленькое хакерское решение, вам нужно добавить subQuery: false вместе к корневому запросу модели

let query = {
   where: where,
   order: orderBy,
   distinct: true,
   offset: offset,
   limit: limit,
   subQuery: false,
   include: [...]
};
...