简体   繁体   English

Sequelize:查询直通表

[英]Sequelize: Querying a through table

I'm trying to query a through table (Application) and paginate/order the results, but can't seem to get the logic quite right.我正在尝试查询一个直通表(应用程序)并对结果进行分页/排序,但似乎无法完全正确地获得逻辑。

The Many-To-Many association:多对多关联:

// Applicants M:N Jobs (through Application)
Applicant.belongsToMany(Job, { through: Application });
Job.belongsToMany(Applicant, { through: Application });

I've queried Application, and then nested the queries for each side of the relation:我查询了应用程序,然后为关系的每一侧嵌套查询:

exports.getApplications = async (req, res, next) => {
    const index = req.query.index || 0;
    const limit = req.query.limit || 10;

    const applications = await Application.findAll({ limit: parseInt(limit, 10), index: parseInt(index)});
    let results = [];

    try {
        await Promise.all(applications.map(async (application) => {
            const job = await Job.findOne({ where: { id: application.jobId } });
            const applicant = await Applicant.findOne({ where: { id: application.applicantId } });

            results.push({application, job, applicant});
        }));

        res.status(200).json({msg: 'success', applications: results});

    } catch(err) {
        console.log(err);
    }
}

It seems to work, but feels a bit hacky.它似乎工作,但感觉有点hacky。 Is there a way of querying the through table and getting the associated data from both the Jobs and Applicant tables at the same time?有没有办法同时从 Jobs 和 Apply 表中查询 through 表并获取相关数据?

Thanks!谢谢!

*EDIT: So I'm trying to return an array of application objects that look something like this: *编辑:所以我试图返回一个看起来像这样的应用程序对象数组:

[
    {
        applicationId: application.id,
        companyId: job.companyId,
        company: job.company.name,
        position: job.title,
        applicantId: applicant.id,
        firstName: applicant.firstName,
        lastName: applicant.lastName,
    }, 
    {...}, 
    {...}
]

...but I'd like to paginate the application results. ...但我想对应用程序结果进行分页。 So:所以:

Application.findAll({ limit, index });

Ideally I'd also then like to be able to order by Job/Applicant properties too理想情况下,我也希望能够通过 Job/Applicant 属性订购

If I understand your requirement properly, I think you want to do this way.如果我正确理解您的要求,我认为您想这样做。

This is an example to order by Applicant.这是申请人订购的示例。

For order by Job, change the order option with Job's attribute.对于按 Job 排序,使用 Job 的属性更改order选项。

When you use the offset/limit, you need the order and the order option needs to ensure the ordering is always same and unique.当您使用偏移量/限制时,您需要order并且order选项需要确保 ordering 始终相同且唯一。

const applications = await Application.findAll({
    include: [
        {                               
            model: Job
        },
        {
            model: Applicant
        }
    ],
    subQuery: false,
    order: [
        ['Applicant', 'lastName'],
        ['Applicant', 'firstName']
        // lastName & firstName is not enough to get a unique order.
        // In order to make sure the order is always same and pagination works properly,
        // you should add either order by id or createdAt/updatedAt. 
        ['Applicant', 'createdAt', 'desc']  
    ],
    offset: index,
    limit,
    raw: true     // To flatten the response.
});

You can give aliases tou your associations and just get你可以给你的协会起别名,然后得到

Applicant.belongsToMany(Job, { through: Application ,as:'jobs'});
Job.belongsToMany(Applicant, { through: Application,as:'applicants' });

Then you'll be able to use a simple include for example Get the job and its applicants with one single query然后,您将能够使用简单的包含,例如通过一个查询获取工作及其申请人

 const job = await Job.findOne({
    where: { id: application.jobId },
    include: ['applicants'],
  });

in your job object you'll get an array of applicants.在您的工作 object 中,您将获得一系列申请人。

More reference for that in here更多参考在这里

With the combination of previous answers结合之前的答案

Applicant.belongsToMany(Job, { through: Application ,as:'jobs'});
Job.belongsToMany(Applicant, { through: Application,as:'applicants' })

with these aliases, you can include both into the application使用这些别名,您可以将两者都包含在应用程序中

const applications = await Application.findAll({
include: [
    {model: Job, as:'jobs',  where: {id: application.jobId}},
    {model: Applicant, as:'applicants' where:{id: application.jobId}}
],
limit,
raw: true
});

also, you can set include as if applicant and job has an association此外,您可以设置包括,好像申请人和工作有关联

{model: Job, as:'jobs',  where: {id: application.jobId} 
   include:[{model:Applicant as:'applicants'}]
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM