我正在为我的阿波罗服务器编写一个解析器(使用sequelize),并且正在努力了解这种向后关联的解析是如何工作的...我对sequelize查询中的include
感到非常困惑工作。
我的模型关联:
User.hasOne(models.Profile) <- so the foreign key 'userId' is on the profile table
Profile.belongsTo(models.User) <- foreign key 'userId' still on profile table
我的graphql模式:
type Profile {
id: ID!
user: User!
}
我的解析器:(我无法使用User
来查询where: {profileId: profile.id}
模型,因为profileId
上没有User
外键)所以...我使用include ..
Profile: {
user: async (profile, _args, { models }) => {
return await models.User.findOne({
include: [{
model: models.Profile,
where: { id: profile.id } <- this makes zero sense to me.. id is the id of the Profile row? how does this work??
}]
})
答案 0 :(得分:1)
使用include
选项,您热切加载指定的关联模型。来自docs:
从数据库中检索数据时,您很有可能还希望获得与同一查询的关联-这称为“渴望加载”。
当您include
关联模型时,Sequelize会在其生成的查询中附加一个join语句。默认情况下,这是一个LEFT OUTER JOIN
。这意味着如果您写:
User.findAll({ include: [{ model: Profile }] })
结果查询将找到所有用户。如果用户碰巧拥有个人资料,则结果中的相关行还将包括个人资料字段。另一方面,我们可以通过添加INNER JOIN
选项将连接强制为required
:
User.findAll({ include: [{ model: Profile, required: true }] })
由于它是INNER JOIN
,因此结果查询仅返回具有配置文件的用户。
在where
内添加include
时,JOIN会自动转换为INNER JOIN
(除非您将required
显式设置为false
)。 where子句实际上实际上成为ON
的{{1}}语句的一部分。因此,如果我们写:
INNER JOIN
结果将包括具有配置文件和的所有用户,该配置文件的ID等于User.findAll({ include: [{ model: Profile, where: { id: 'someId' } }] })
。 someId
始终特定于我们要包括的模型,因此无需指定我们感兴趣的模型的where
字段。
最后,如果使用id
而不是findOne
,则Sequelize会简单地向查询添加findAll
的1,并且该方法将解析为Model的单个实例而不是数组。
关于联接的完整讨论不在此问题的范围内。您可以查看其他问题以获取更多详细信息: