Вот пример:
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 } ]