Sequelize: findAll с помощью include, где id находится в jsonb - PullRequest
0 голосов
/ 02 февраля 2020

Вот мой запрос

Car.findAll({
  attributes: ['id'],
  include: [
    {
         model: Sedan,
         where: {
           id:{                    
                 [Op.in]: [sequelize.col('car.favorites')]
           }
         }
     }
  ]
})

Я хочу включить все саданы, где «id» садана совпадает с одним из идентификаторов, хранящихся в массиве «избранное» jsonb, который является частью «машины». "table.

Выше приведена моя попытка со многими другими, но она не в состоянии прочитать столбец jsonb.

Какой лучший способ добиться того, что я пытаюсь сделать? выше

1 Ответ

0 голосов
/ 12 февраля 2020

Вот пример:

index.ts:

import { sequelize } from '../../db';
import Sequelize, { Op } from 'sequelize';
import assert from 'assert';

class Car extends Sequelize.Model {}
Car.init(
  {
    favorites: {
      type: Sequelize.JSONB,
    },
  },
  { sequelize, modelName: 'Car' },
);

class Sedan extends Sequelize.Model {}
Sedan.init({}, { sequelize, modelName: 'Sedan' });

Car.hasMany(Sedan);

(async function test() {
  try {
    await sequelize.sync({ force: true });
    // seed
    await Car.create({ favorites: [1, 5, 6], Sedans: [{ id: 1 }, { id: 2 }] }, { include: [Sedan] });

    const cars = await Car.findAll({
      attributes: ['id'],
      include: [
        {
          model: Sedan,
          where: {
            id: {
              [Op.in]: [Sequelize.literal(`select jsonb_array_elements_text(favorites)::integer from "Car"`)],
            },
          },
        },
      ],
    });
    assert(cars[0].Sedans.length === 1, 'The count of sedans is not correct');
    console.log(cars[0].Sedans);
  } catch (error) {
    console.log(error);
  } finally {
    await sequelize.close();
  }
})();

После сохранения начальных данных в базе данных мы имеем следующие записи:

node-sequelize-examples=# select * from "Car";
 id | favorites
----+-----------
  1 | [1, 5, 6]
(1 row)

node-sequelize-examples=# select * from "Sedan";
 id | CarId
----+-------
  1 |     1
  2 |     1
(2 rows)

node-sequelize-examples=# select * from "Car" as c
node-sequelize-examples-# left join "Sedan" as s on c.id = s."CarId"
node-sequelize-examples-# where s.id in (select jsonb_array_elements_text(favorites)::integer from "Car");
 id | favorites | id | CarId
----+-----------+----+-------
  1 | [1, 5, 6] |  1 |     1
(1 row)

Необработанный SQL запрос выглядит так:

select * from "Car" as c
left join "Sedan" as s on c.id = s."CarId"
where s.id in (select jsonb_array_elements_text(favorites)::integer from "Car")

Журнал результатов запроса, как и ожидалось:

[ Sedan {
    dataValues: { id: 1, CarId: 1 },
    _previousDataValues: { id: 1, CarId: 1 },
    _changed: {},
    _modelOptions:
     { timestamps: false,
       validate: {},
       freezeTableName: true,
       underscored: false,
       paranoid: false,
       rejectOnEmpty: false,
       whereCollection: null,
       schema: null,
       schemaDelimiter: '',
       defaultScope: {},
       scopes: {},
       indexes: [],
       name: [Object],
       omitNull: false,
       sequelize: [Sequelize],
       hooks: {} },
    _options:
     { isNewRecord: false,
       _schema: null,
       _schemaDelimiter: '',
       include: undefined,
       includeNames: undefined,
       includeMap: undefined,
       includeValidated: true,
       raw: true,
       attributes: undefined },
    isNewRecord: false } ]
...