当包含模型时,Sequelize 查询返回错误的行数 (findAndCountAll)
Sequelize query returning the wrong number of rows when models are included (findAndCountAll)
下面的代码应该 return 12 行 (req.query.limit
= 12)。如果我不包含任何关联的行,这很好用,但是当我包含相关模型时,它 returns 7 行。
我 认为 这取决于我使用 属性 subQuery: false
这允许我(如果我没记错的话)正确地按列排序我的结果 -不过好久没看订货码了,对sequelize不是很熟练,不想无谓的破解!
如果有人能发现我哪里出错了,我将不胜感激,也许为什么?
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);
}
协会:
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 });
为了正确使用 findAndCountAll
,您需要去掉 include
选项中的 many-to-many
或将其转换为 one-to-many
并使用 separate: true
选项.
协会
Company.hasMany(Contact, { foreginKey: 'companyId' });
Contact.belongsTo(Person, { foreginKey: 'personId' });
可能包含选项
{
model: Company,
attributes: [ 'id', 'name' ],
include: [
{
model: Contact,
separate: true,
attributes: [],
include: [{
model: Person,
attributes: [ 'firstName', 'lastName', 'phone', 'email' ]
}]
}
]
}
是的,你会得到一个额外的等级,通过Contact
获得人物属性。
下面的代码应该 return 12 行 (req.query.limit
= 12)。如果我不包含任何关联的行,这很好用,但是当我包含相关模型时,它 returns 7 行。
我 认为 这取决于我使用 属性 subQuery: false
这允许我(如果我没记错的话)正确地按列排序我的结果 -不过好久没看订货码了,对sequelize不是很熟练,不想无谓的破解!
如果有人能发现我哪里出错了,我将不胜感激,也许为什么?
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);
}
协会:
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 });
为了正确使用 findAndCountAll
,您需要去掉 include
选项中的 many-to-many
或将其转换为 one-to-many
并使用 separate: true
选项.
协会
Company.hasMany(Contact, { foreginKey: 'companyId' });
Contact.belongsTo(Person, { foreginKey: 'personId' });
可能包含选项
{
model: Company,
attributes: [ 'id', 'name' ],
include: [
{
model: Contact,
separate: true,
attributes: [],
include: [{
model: Person,
attributes: [ 'firstName', 'lastName', 'phone', 'email' ]
}]
}
]
}
是的,你会得到一个额外的等级,通过Contact
获得人物属性。