表达和续集:急切加载属于许多关联挂起应用程序

时间:2018-01-01 00:29:02

标签: javascript node.js performance express sequelize.js

我正在尝试加载belongs-to-many关联,我正在加载三个嵌套关联。以下是模型,其中包含三个数据库表programsprogramDatespeopleProgramDates

program.js

module.exports = function(sequelize, DataTypes) {
  const Program = sequelize.define('program', {
    name: DataTypes.STRING
  });

  Program.associate = ({programDate}) => {
    Program.hasMany(programDate);
  };

  return Program;
};

program_date.js

module.exports = function(sequelize, DataTypes) {
  const ProgramDate = sequelize.define('programDate', {
    date: DataTypes.DATEONLY,
    volunteerLimit: DataTypes.INTEGER
  }, {
    indexes: [
      {
        unique: true,
        fields: ['programId', 'date']
      }
    ]
  });

  ProgramDate.associate = ({program, person}) => {
    ProgramDate.belongsTo(program);
    ProgramDate.belongsToMany(person, {through: 'peopleProgramDates'});
  };

  return ProgramDate;
};

在我的控制器中,我想返回一个包含所有程序的对象,programDates和peopleProgramDates:

const {bus, family, person, volunteerType, program, programDate} = require('../models');

exports.get = (request, response) => {
  return Promise.all([
    bus.findAll({ include: [{model: family, include: [person]}] })
        .then(buses => buses.map(addBusCount)),
    volunteerType.findAll({include: [person]})
        .then(volunteerTypes => volunteerTypes.map(addVolunteerCount)),

    // this query hangs the application
    program.findAll( { include: [{ model: programDate, include: [{association: 'peopleProgramDates'}] }]} )
        .then(programs => programs.map(processPrograms))

  ])
      .then(([buses, volunteerTypes, programs]) =>
        response.render('pages/register', {
          buses,
          volunteerTypes,
          programs
        })
      );
};

目前,processPrograms()是一个只返回相同对象数组的函数,所以在这里不应该相关。 <{1}}和addBusCount同样不具备相关性。

我认为问题可能是人们的程序日期不是真正的续集模型,而是addVolunteerCountbelongsToMany through:关联的结果。

This post似乎建议我可以使用ProgramDate属性来加载association:关联中的数据,但查询会挂起应用程序。

如果从查询中删除连接表,则数据加载正常:

through

奖励积分:最终我真正需要的只是与program.findAll( { include: [programDate] } ) 个对象一起返回peopleProgramDates的计数。也许我可以简单地在programDate模型上定义这样的模型,但是我们也许可以在一个单独的问题中解决这个问题。然而,如果有令人信服的理由使用这种方法,例如性能,那么也许我们应该采用这种方式。

1 个答案:

答案 0 :(得分:0)

解决方案是通过关联为belongsToMany添加别名:

// program_date.js
ProgramDate.belongsToMany(person, {through: 'peopleProgramDates', as: 'peopleProgDates'});

然后引用include属性中的别名:

program.findAll( { include: [{ model: programDate, include: [{association: 'peopleProgDates'}] }]} )