У меня есть следующие модели секвенирования:
import { DataTypes, Model } from 'sequelize';
class A extends Model{}
A.init {
name: DataTypes.STRING,
start_date: DataTypes.DATE,
end_date: DataTypes.DATE,
deleted: DataTypes.BOOLEAN
}
class B extends Model {}
B.init {
a_id: DataTypes.Integer,
text: DataTypes.String,
created_at: DataTypes.STRING,
updated_at: DataTypes.DATE,
}
B.belongsTo(A);
A.hasMany(B);
Я пытаюсь выполнить запрос, чтобы получить первые 50 записей A с левым внешним соединением B. По какой-то причине я получаю только 49 записей. Что странно, если я возьму запрос, сгенерированный в свойстве logging, и воспользуюсь таким инструментом, как DBeaver, я получу все 50 строк.
Вот как создается запрос:
const params = {
limit: 50,
offset: 0,
order: [ [ 'id', 'desc']],
attributes: [
'id',
'name',
'start_date',
'end_date',
],
subQuery: false,
where: { deleted: false },
include: [{model: B}],
logging: console.info
}
const results = await A.findAll(params);
//length of results is 49
А вот запрос, который генерируется свойством logging:
(Обратите внимание, что я не включил все столбцы в список для удобства чтения)
SELECT *
FROM "A" LEFT OUTER JOIN B ON "A"."id" = "B"."a_id"
WHERE "A"."deleted" = false
ORDER BY "A"."id" DESC
LIMIT 50 OFFSET 0;
Запрос Sequelize возвращает 49 строк. Запрос, созданный на основе запроса Sequelize, возвращает 50.
Некоторые другие точки данных
Обновлять:
const results = await this.A.findAll(findParams);
console.info('Final results: ', results.length);
🤔 А знаете ли вы, что...
Node.js поддерживает платформу Event Loop, что обеспечивает высокую производительность при обработке запросов.
По умолчанию Sequelize объединит связанную модель во внутренний массив. Из-за композиции при подсчете длины результата фактически подсчитывается количество различных записей модели A
.
Бывший:
SQL-вывод
| id | name | a_id | text |
| 1 | a1 | 1 | b1 |
| 1 | a1 | 1 | b2 |
| 2 | a2 | 2 | b3 |
Это будет составлено в
[
{
"id": 1,
"name": "a1",
"b" : [
{
"text": "b1"
},
{
"text": "b2"
}
]
},
{
"id": 2,
"name": "a2",
"b": [
{
"text": "b3"
}
]
}
]
Если вы подсчитаете длину родительского массива, вы увидите 2, а вывод SQL — 3. На самом деле вам нужно посчитать количество элементов во внутренних массивах, которое должно соответствовать счетчику SQL.
Если вы не хотите, чтобы Sequelize компоновал таким образом, вы можете отключить эту композицию,
params = {
...
raw: true,
nest: true
}