sequelize.js - 在 sequelize 和 apollo-server 中从目标解析源关联时理解“包含”
问题描述
我正在为我的 apollo-server 编写一个解析器(使用 sequelize),并且正在努力理解这种向后关联的解析是如何工作的……我对include
我的 sequelize 查询中的工作方式感到非常困惑。
我的模特协会:
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
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??
}]
})
解决方案
通过使用该include
选项,您可以急切地加载指定的关联模型。从文档:
当您从数据库中检索数据时,您很有可能还希望获得与同一查询的关联——这称为急切加载。
当您include
关联模型时,Sequelize 会在其生成的查询中附加一个连接语句。默认情况下,这是一个LEFT OUTER JOIN
. 这意味着如果你写:
User.findAll({ include: [{ model: Profile }] })
结果查询将找到所有用户。如果用户碰巧有个人资料,结果中的相关行也将包括个人资料字段。另一方面,我们可以INNER JOIN
通过添加required
选项来强制连接为:
User.findAll({ include: [{ model: Profile, required: true }] })
因为它是INNER JOIN
,所以生成的查询仅返回具有配置文件的用户。
当您在where
中添加 a 时include
,JOIN 会自动转换为 an INNER JOIN
(除非您明确设置required
为false
)。ON
where子句本身实际上成为INNER JOIN
. 所以如果我们写:
User.findAll({ include: [{ model: Profile, where: { id: 'someId' } }] })
结果将包括所有拥有个人资料并且该个人资料的 id 等于 的用户someId
。总是特定于我们所包含的where
模型,因此无需指定id
我们感兴趣的模型字段。
最后,如果使用findOne
而不是findAll
,Sequelize 只需将 a LIMIT
of 1 添加到查询中,并且该方法解析为 Model 的单个实例而不是数组。
对连接的完整讨论超出了这个问题的范围。您可以查看这些其他问题以获取更多详细信息:
推荐阅读
- c# - System.StackOverflowException C#
- authentication - why auth is frequently implemented using 2 redirects
- java - React JS 添加计数 JSON 元素
- php - 使用带有键值的数组的 php CURL 请求
- html - Blogger Emporio 主题:在主页片段上永久显示 Drop-Shadow
- java - 如何解决此问题“标准输出不应直接用于记录任何内容”
- contiki - RPL存储方式访问路由表(Contiki / Cooja)
- database - MongoDB $lookup 基于两种模式
- java - 使用和不使用组的 java 中正则表达式的不同行为
- flutter - 如何从 TextField 聚焦到 DropdownButton