在Sequelize中查找与其他模型中的多个(所有)实例关联的实例

时间:2018-02-08 12:19:27

标签: javascript sql database join sequelize.js

Simplified Sequelize模型示例:

Post.belongsToMany(Tag)
Tag.belongsToMany(Post)

我如何findAll与所有标签相关联的帖子?

示例数据集:

post
{ id: 1 }
{ id: 2 }

tag
{ id: 10 }
{ id: 11 }

post_tag
{ post_id: 1, tag_id: 10 }
{ post_id: 2, tag_id: 10 }
{ post_id: 2, tag_id: 11 }

因此,如果相关代码 10 11 ,则查询应返回发布2 ,因为它与两个代码相关联,但不发布1 ,因为它与所有标记无关。 (标签的数量当然可以超过两个)

1 个答案:

答案 0 :(得分:0)

可能有一种方法可以在一个Sequelize findAll请求中构造此请求,但我不得不使用原始SQL来完成您的任务。这有两种方法:

1。获取帖子ID并使用结果

查询Post.findAll

查找包含所有标记的post_ids

const postIds = await db.query(`
  SELECT post_id FROM (
    SELECT post_id, COUNT(*) AS counter
    FROM post_tag
    GROUP BY post_id
  ) AS tbl
  WHERE counter = (SELECT count(*) as COUNT from tags);;
`, {type: db.QueryTypes.SELECT})

查找postIds数组

中的帖子
const posts = await Post.findAll({
  where: {
    id: {
      $in: postIds.map(x => x.post_id)
    }
  }
});

2。在一个SQL语句中获取帖子

const posts = await db.query(`
  SELECT *
  FROM posts
  WHERE id IN (
    SELECT post_id FROM (
      SELECT post_id, COUNT(*) AS counter
      FROM post_tag
      GROUP BY post_id
    ) AS tbl
    WHERE counter = (SELECT count(*) as COUNT from tags)
  )
`, {type: db.QueryTypes.SELECT});

(fwiw,我添加了两种方法,因为我更喜欢在应用程序代码中使用较少的原始SQL)