关于 sequelize.js:Sequelize 关联导致子查询

Sequelize Associations Causing Sub-Query

我的应用程序中有一个功能,可以作为博客文章的活动源(类似于 Tumblr)。在此页面的路由中,我的主要查询在我的博客文章表上,并且我将包含其他元信息和评论的表加入到此表中,以便为每个博客文章提供功能齐全的卡片。这些表来自我的类??别(对帖子进行分类)、主题(感兴趣的主题)、附加的文件(文件/图像)和评论(评论帖子)表。

使用我当前的查询,我可以毫无问题地加入所有这些表,但我遇到了与博客文章上的父查询关联的 where 子句的问题。当 filecomment 表连接时,会发生一个子查询,我认为这与博客文章和这些表之间的关联类型有关,并以某种方式影响结果。

提供的是模式和关联:

blog_post

  • blog_id
  • 日期
  • 内容
  • 类别ID
  • topic_id

协会

  • belongsTo(user, { foreignKey: 'user_id' });
  • belongsTo(category, { foreignKey: 'category_id' });
  • belongsTo(topic, { foreignKey: 'topic_id' });
  • hasMany(file, { foreignKey: 'blog_id' });
  • hasMany(comment, { foreignKey: 'blog_id' });

用户

  • 用户身份
  • 组织 ID

类别

  • 类别ID
  • 类别

协会

  • hasMany(blog_post, { foreignKey: 'category_id'})

主题

  • topic_id
  • 话题

协会

  • hasMany(blog_post, { foreignKey: 'topic_id'})

文件和注释表在其架构文件中没有与此问题相关的关联。

提供的是查询(请不要驼峰式是上面列名的别名)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
models.BlogPost.findAll({
            order: 'Date DESC',
            include: [{
                model: models.User,
                where: { organizationId: req.user.organizationId },
                attributes: ['userId', 'firstName', 'lastName'],
                required: false,
            },
            {
                model: models.Topic,
                attributes: ['topic'],
                required: false
            },
            {
                model: models.Category,
                attributes: ['category'],
                required: false
            },
            {
                model: models.File,
                attributes: ['file'],
                required: false
            },
            {
                model: models.Comment,
                include: [{
                    model: models.User,
                    attributes: ['userId','firstName', 'lastName']
                }],
                required: false
            }],
            limit: 10
        })

使用子查询更新:

1
2
3
4
5
6
7
8
9
SELECT `blog_post`.*, `user`.`user_id`, `user`.`first_name`, `user`.`last_name`, `topic`.`topic_id`, `topic`.`topic`, `category`.`category_id`, `category`.`category_name`, `file`.`file_id`, `file`.`file`, `comment`.`comment_id`, `comment`.`comment`, `comment`.`blog_id`, `comment`.`user_id`, `comment`.`created_at`, `comment`.`updated_at`, `comment`.`blog_id`, `comment`.`user_id`, `comment.user`.`user_id`
FROM (SELECT `blog_post.`blog_id`, `blog_post.`date`, `blog_post.`title`, `blog_post.`content`, `blog_post.`topic_id`, `blog_post.`category_id`, `blog_post.`user_id`, `blog_post.`created_at`, `blog_post.`updated_at`, `blog_post.`user_id`, `blog_post.`topic_id`, `blog_post.`category_id` FROM `blog_post LIMIT 10) AS `blog_post
LEFT OUTER JOIN `user` AS `user` ON `blog_post.`user_id` = `user`.`user_id` AND `user`.`organization_id` = 1
LEFT OUTER JOIN `topic` AS `topic` ON `blog_post.`topic_id` = `topic`.`topic_id`
LEFT OUTER JOIN `category` AS `category` ON `blog_post.`category_id` = `category`.`category_id`
LEFT OUTER JOIN `file` AS `file` ON `blog_post.`blog_id` = `file`.`blog_id`
LEFT OUTER JOIN `comment` AS `comment` ON `blog_post.`blog_id` = `comment`.`blog_id`
LEFT OUTER JOIN `user` AS `comment.user` ON `comment`.`user_id` = `comment.user`.`user_id`
ORDER BY date DESC;


您可能需要在 findAll 方法的 options 对象中添加 subQuery: false。但是,此选项在 sequelize 文档中不存在,您可以在 source code 中找到它。如果未设置,则默认为 true 并导致添加您在查询中存在 LIMIT 选项时提到的子查询。


我遇到了同样的问题。我将 subQuery:false 与 where 语句对象一起使用。

喜欢:--

1
2
3
4
5
{
include:[{model:childrens,attributes:['id','firstName']}],
where:{'$childrens.id$':12}
subQuery:false
}

但您需要记住,如果您在 where 语句中使用内部表
那么你将不得不使用:--

1
where:{'$childrens.id$':12}

因为如果你不使用'$',它会自动创建类似:

abcd(main table).childrens.id=12

所以要检查孩子 id 上的 id 值,然后你会
必须使用'$'。

就是这样。希望它对你有用。