Sequelize在查询

时间:2017-12-24 13:38:15

标签: mysql node.js sequelize.js

我在这两个模型之间的MSQL表中有多对多的关系:

  
      
  • 场地 - 代表可以拥有多个业主(员工)的场地
  •   
  • 员工 - 代表可以是首席执行官或销售员工或任何人的员工。
  •   

我正在使用设置关系,如下所示:

关系员工>地点

 Employee.associate = function (models) { 
   models.Employee.belongsToMany(models.Venue, { through: 'EmployeeVenues' })
 }

关系地点>雇员

 Venue.associate = function (models) {
    models.Venue.belongsToMany(models.Employee, { through: 'EmployeeVenues' })
 }

Sequelize docs

  

根据Sequelize docs,它将创建一个名为EmployeeVenues的新模型,其中包含等效的外键employee_id和venue_id。需要定义。 Sequelize之前会尝试自动生成名称,但这并不总能导致最合理的设置。这会将方法 getVenues ,setVenues,addVenue,addUsers添加到Employee。

这是正确的工作,当我启动我的Sequelize时,它会创建一个名为EmpoyeeVenues的新表,并使用正确的外键作为复合键。但是,当我查询getVenues时,它不会返回预期的输出。相反,它也返回相关的表值,这是我不想要的。

查询以获取属于id等于1

的员工的所有场所
router.get('/api/v1/users/:employee_id/venues', (request, response) => {
  var employeeId = request.params.employee_id;

  models.Employee.findOne({
    where: {id: employeeId}
  }).then((employee) => {

    if(!employee) { return response.status(400).send("Employee doesnt have a venue registered yet.")}
    var venues = employee.getVenues().then((venues) => {
    response.status(200).send(venues);
  })
})
});

响应结果

[
    {
        "id": 1,
        "capacity": "11",
        "venue_name": "Club Fix",
        "venue_description": "Club in Tilburg",
        "EmployeeVenues": {
            "employee_id": 1,
            "venue_id": 1
        }
    },
    {
        "id": 2,
        "capacity": "400",
        "venue_name": "Club Vie",
        "venue_description": "Club in Rotterdam",
        "EmployeeVenues": {
            "employee_id": 1,
            "venue_id": 2
        }
    }
]

问题

  

为什么Sequelize提供的此查询中包含EmployeeVenues?如何防止EmployeeVenues被包含在响应中?


更新

  

根据2014年制作的Sequelize github页面上的一个问题,有一个可行的解决方案

https://github.com/sequelize/sequelize/issues/2143

    User.find({
    where: {id: userId}, attributes: userFields,
    include: [
      {model: db.Role, attributes: roleFields, through: {attributes: []}}
    ]
});

但它与Sequelize文档中的文档版本不符,该文档是最新的,至少它应该是。

User.findAll({
  include: [{
    model: Project,
    through: {
      attributes: ['createdAt', 'startedAt', 'finishedAt'],
      where: {completed: true}
    }
  }]
});

甚至在reference documentation:

上简单陈述
user.getPictures() // gets you all pictures

2 个答案:

答案 0 :(得分:2)

更新

  

根据2014年制作的Sequelize github页面上的问题,有一种解决方案有效

https://github.com/sequelize/sequelize/issues/2143

    User.find({
    where: {id: userId}, attributes: userFields,
    include: [
      {model: db.Role, attributes: roleFields, through: {attributes: []}}
    ]
});

但是它与最新的Sequelize文档中的文档版本不匹配,至少应该如此。


User.findAll({
  include: [{
    model: Project,
    through: {
      attributes: ['createdAt', 'startedAt', 'finishedAt'],
      where: {completed: true}
    }
  }]
});

甚至在reference documentation:

上也很简单
user.getPictures() // gets you all pictures

答案 1 :(得分:2)

我认为给出的答案遗漏了一件重要的事情-在哪里将所包含的模型中需要的属性保留在这里-项目。 github上的issue有最终答案,但仍然不是我期待的完整答案。

我们需要在模型级别重新指定属性,然后将联接表属性设置为无。

User.findAll({
  include: [{
    model: Project,

    through: 'JoinTableAliasName' /// only if exist/needed
    as: 'modelAssociationAlias' // only if exist/needed

    // attributes needed from Project table
    attributes: ['createdAt', 'startedAt', 'finishedAt'],

    through: { // through again doesn't create any issue
      attributes: [], // this helps removing the join table in returned data
      where: {completed: true}
    }
  }]
});