Sequelize:通过 table 查询 a

Sequelize: Querying a through table

我正在尝试通过 table(应用程序)和 paginate/order 查询结果,但似乎无法完全正确地理解逻辑。

多对多关联:

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

我查询了应用程序,然后嵌套了关系每一侧的查询:

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);
    }
}

似乎可行,但感觉有点老套。有没有一种方法可以通过 table 查询并同时从职位和申请人 table 获取相关数据?

谢谢!

*编辑:所以我正在尝试 return 一组看起来像这样的应用程序对象:

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

...但我想对申请结果进行分页。所以:

Application.findAll({ limit, index });

理想情况下,我也希望能够通过 Job/Applicant 属性进行订购


更多信息:

感谢到目前为止的帮助,看来我还需要为应用程序和 Job/Applicant 创建一个 belongsTo 关联,以便我可以查询关联 table 并获得Job/Applicant数据:

// Applicants M:N Jobs (through Application)
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' }});

我目前使用 applicant.addJob(currentJob);

在我的其中一条路线中创建了一个应用程序

//申请人模型:

const Applicant = sequelize.define('applicant', {
    id: {
        type: Sequelize.INTEGER,
        autoIncrement: true,
        primaryKey: true,
        allowNull: false
    },
    cvUrl: {
        type: Sequelize.STRING,
        allowNull: true
    }
});

// 职位模型:

const Job = sequelize.define('job', {
    id: {
        type: Sequelize.INTEGER,
        autoIncrement: true,
        allowNull: false,
        primaryKey: true
    },
    title: {
        type: Sequelize.STRING,
        allowNull: false
    },

    // **snip**

    createdAt: {
        type: Sequelize.DATE(3),
        allowNull: false,
    },
    updatedAt: {
        type: Sequelize.DATE(3),
        allowNull: false,
    }
});

// 应用模型:

const Application = sequelize.define('application', {
    id: {
        type: Sequelize.INTEGER,
        primaryKey: true,
        autoIncrement: true,
        notNull: true
    }
});

如果我正确理解你的要求,我想你想这样做。

这是申请人订购的示例。

对于按作业排序,请将 order 选项更改为作业的属性。

当您使用 offset/limit 时,您需要 order 并且 order 选项需要确保顺序始终相同且唯一。

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.
});

你可以给你的协会起别名,这样就可以

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

然后你就可以使用一个简单的包含 例如通过一个查询获取工作及其申请人

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

在您的工作对象中,您将获得一系列申请人。

here

中的更多参考

结合前面的答案

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

使用这些别名,您可以将两者都包含在应用程序中

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
});

此外,您可以设置包含,就好像申请人和工作有关联一样

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