如何通过两个外键将模型与另一个模型关联? (续集)

时间:2015-02-18 17:31:32

标签: node.js sequelize.js

让我们想象一下情况

您有两种型号: 带有属性的 event_user id 带有属性的 event_user_message user_from_id,user_to_id

您希望获得与用户X联系的 20 event_users(通过消息/ s)

关联定义

EventUser.hasMany(eventUserMessages, as: "from", foreignKey: "user_from_id")
EventUser.hasMany(eventUserMessages, as: "to", foreignKey: "user_to_id")

EventUserMessages.belongsTo(eventUser, as: "from", foreignKey: "user_from_id")
EventUserMessages.belongsTo(eventUser, as: "to", foreignKey: "user_to_id")

解决方案1 ​​ 问题在这种情况下,我只获得有两种方式对话的用户

var include,limit,where; limit = parameters.limit? parameters.limit:20;

include.push({
  model: models.eventUserMessages,
  as: "to",
  where: {user_from_id: parameters.inConnectionWith}
  attributes: []
});

include.push({
  model: models.eventUserMessages,
  as: "from",
  where: {user_to_id: parameters.inConnectionWith}
  attributes: []
});

eventUserModel.findAll({
  include: include,
  where: where
})

解决方案2 在此解决方案中,您将获得所有预期结果 问题在此解决方案中,您无法使用限制(不起作用)

include.push({
  model: models.eventUserMessages,
  as: "to",
  required: false,
  attributes: []
});

include.push({
  model: models.eventUserMessages,
  as: "from",
  required: false,
  attributes: []
});

where = Sequelize.and(where, Sequelize.or({
  "to.user_from_id": parameters.inConnectionWith
}, {
  "from.user_to_id": parameters.inConnectionWith
}));

eventUserModel.findAll({
  include: include,
  where: where
})
如果您提供有关如何实现此目的的一些建议,

将会很感激

先谢谢

1 个答案:

答案 0 :(得分:0)

你让自己感到困惑。在您的第一个解决方案中,通过:

include.push({
  model: models.eventUserMessages,
  as: "to",
  where: {user_from_id: parameters.inConnectionWith}
  attributes: []
});

您实际上是在EventUser.id = EventUserMessages.user_to_id WHERE EventUserMessages.user_from_id = parameters.inConnectionWith上进行加入。

联接已将结果集缩减为包含user_to_id = parameters.inConnectionWith的结果集。然后,您的where条件会将结果缩小到user_to_id = parameters.inConnectionWith

这为您提供了通过双向通信返回用户的结果。如果你不明白为什么,请看下面的答案:

include.push({
  model: models.eventUserMessages,
  as: "to",

  //firstly, you don't need this.
  //Secondly, if anything, it should be user_to_id, which won't do anything.
  /* where: {user_to_id: parameters.inConnectionWith} */ 

  attributes: []
});

但是,如果您的数据集不需要event_user表中的属性,则不需要在这种情况下使用包含。拿出来,你的解决方案1应该可以正常工作。

运行下面建议的查询效率要高得多:

EventUserMessages.findAll({
    where: Sequelize.or(
        { user_from_id: parameters.inConnectionWith },
        { user_to_id: parameters.inConnectionWith }
    },
    limit: 20,
    order: [ you need to order them so you will return the relevant 20 datasets ]
});