[英]Sequelize query returning the wrong number of rows when models are included (findAndCountAll)
The following code should return 12 rows ( req.query.limit
= 12).以下代码应返回 12 行 ( req.query.limit
= 12)。 This works fine if I don't include any associated rows, but when I include the related models it returns 7 rows.如果我不包含任何关联的行,这就可以正常工作,但是当我包含相关模型时,它会返回 7 行。
I think it's down to me using the property subQuery: false
which allows me (if I remember correctly) to order my results by column correctly - but it's been a long time since I've looked at the ordering code, I'm not very proficient with sequelize, and don't want to break it unnecessarily!我认为这取决于我使用属性subQuery: false
这允许我(如果我没记错的话)按列正确地排序我的结果 - 但是我已经很长时间没有看过排序代码了,我不是很精通sequelize,不想无谓破坏!
Would really appreciate it if someone can spot where I'm going wrong, and maybe why?如果有人能发现我哪里出错了,我会非常感激,也许为什么?
exports.getApplications = async(req, res, next) => {
const index = req.query.index || 0;
const limit = req.query.limit || 10;
const order = req.query.orderDirection || 'DESC';
let orderFields;
switch(req.query.orderField) {
case 'lastName':
orderFields = [
['applicant', 'person', 'lastName'],
['applicant', 'person', 'firstName'],
['applicant', 'createdAt', order]
];
break;
default:
orderFields = [ 'createdAt' ];
}
try {
const applications = await Application.findAndCountAll({
include: [
{
model: Job,
include: [
{
model: Company,
attributes: [ 'id', 'name' ],
include: [
{
model: Person,
attributes: [ 'firstName', 'lastName', 'phone', 'email' ]
}
]
}
]
},
{
model: Applicant,
include: [
{
model: Person,
attributes: [ 'id', 'firstName', 'lastName', 'email', 'phone', 'createdAt' ]
}
],
}
],
subQuery: false,
order: orderFields,
limit: parseInt(limit, 10),
offset: parseInt(index),
distinct: true,
attributes: [
'id',
'applicantId',
'jobId',
[Sequelize.fn('date_format', Sequelize.col('application.createdAt' ), '%d/%m/%y'), 'applicationDate']
]
});
console.log(applications.rows.length); // 7 -- wrong
console.log(limit); // 12 -- correct
res.status(200).json({msg: 'success', applications: applications});
} catch (err) {
console.log(err);
}
Associations:协会:
Company.hasMany(Job, { foreignKey: { name: 'companyId', allowNull: false} });
Job.belongsTo(Company, { foreignKey: { name: 'companyId', allowNull: false} });
Person.hasOne(Applicant, { foreignKey: { name: 'personId', allowNull: false, unique: true } });
Applicant.belongsTo(Person, { foreignKey: { name: 'personId', allowNull: false, unique: true } });
Applicant.belongsToMany(Job, { through: Application });
Job.belongsToMany(Applicant, { through: Application });
// Set associations so the Application table can be queried directly
Application.belongsTo(Job, { foreignKey: { name: 'jobId' }});
Application.belongsTo(Applicant, { foreignKey: { name: 'applicantId' } });
Person.belongsToMany(Company, { through: Contact });
Company.belongsToMany(Person, { through: Contact });
In order to properly use findAndCountAll
you need to get rid of many-to-many
in include
option OR convert it to one-to-many
and use separate: true
option.为了正确使用findAndCountAll
,您需要摆脱include
选项many-to-many
或将其转换one-to-many
并使用separate: true
选项。
associations协会
Company.hasMany(Contact, { foreginKey: 'companyId' });
Contact.belongsTo(Person, { foreginKey: 'personId' });
possible include option可能包括选项
{
model: Company,
attributes: [ 'id', 'name' ],
include: [
{
model: Contact,
separate: true,
attributes: [],
include: [{
model: Person,
attributes: [ 'firstName', 'lastName', 'phone', 'email' ]
}]
}
]
}
And yes, you will get an extra level to get person attributes through Contact
.是的,您将获得额外的级别以通过Contact
获取人员属性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.