Select 包含所有标签的文章(通过 habtm 关系)
Select Article which has ALL tags (via habtm relation)
我有 has_and_belongs_to_many 标签的文章模型。
我想查找指定了标签的文章,例如 tags = ["tag1, "tag2", "tag"3]
最好在 sql 查询中包含所有内容。 (使用 Postgresql)
看来使用 Postgresql 数组会很好。
目前,我正在研究这种方法:
select "articles".*,
(
select array(
select tags.name from tags
inner join articles_tags on articles_tags.tag_id = tags.id and articles_tags.article_id = articles.id
)
) as tags
FROM "articles"
我正在尝试执行标记 && ARRAY[?] 并传递标记,但它不起作用,因为 'tags is not a column'.
也许你可以推荐优雅的rails方式解决方案。
UPD
看起来像这样 sql 满足了需要,但看起来不太 Rails 友好:
select articles.*
from articles
where articles.id in (
select t.id
from (
select articles.id, array_agg(articles_tags.tag_id) as tag_ids
from articles
inner join articles_tags on articles_tags.article_id = articles.id
group by articles.id
) as t
where t.tag_ids @> array[2,3]
)
有什么方法可以做到Rails吗?
谢谢!
您可以尝试这样的操作:
required_tags = ["tag1", "tag2", "tag3"]
Article.joins(:tags)
.where(tags: { name: required_tags })
.group('articles.id')
.having('count(*) = ?', required_tags.count)
它的作用是:
- 获取所有有标签的文章
- 其中包含所需标签之一
- 将它们分组,例如,当文章具有标签 "tag1"、"tag2" 和 "tag3" 时,我们有一组 3 个,或者只有一组 2 个,当文章有标签 "tag1"、"tag2" 和 "tag4".
- 然后只选择那些成员数量与我们所需的标签数组中指定的数量相同的组。
可能有更好的方法来实现您想要的,但这确实是我目前能想到的唯一解决方案。
我有 has_and_belongs_to_many 标签的文章模型。
我想查找指定了标签的文章,例如 tags = ["tag1, "tag2", "tag"3]
最好在 sql 查询中包含所有内容。 (使用 Postgresql)
看来使用 Postgresql 数组会很好。
目前,我正在研究这种方法:
select "articles".*,
(
select array(
select tags.name from tags
inner join articles_tags on articles_tags.tag_id = tags.id and articles_tags.article_id = articles.id
)
) as tags
FROM "articles"
我正在尝试执行标记 && ARRAY[?] 并传递标记,但它不起作用,因为 'tags is not a column'.
也许你可以推荐优雅的rails方式解决方案。
UPD
看起来像这样 sql 满足了需要,但看起来不太 Rails 友好:
select articles.*
from articles
where articles.id in (
select t.id
from (
select articles.id, array_agg(articles_tags.tag_id) as tag_ids
from articles
inner join articles_tags on articles_tags.article_id = articles.id
group by articles.id
) as t
where t.tag_ids @> array[2,3]
)
有什么方法可以做到Rails吗?
谢谢!
您可以尝试这样的操作:
required_tags = ["tag1", "tag2", "tag3"]
Article.joins(:tags)
.where(tags: { name: required_tags })
.group('articles.id')
.having('count(*) = ?', required_tags.count)
它的作用是:
- 获取所有有标签的文章
- 其中包含所需标签之一
- 将它们分组,例如,当文章具有标签 "tag1"、"tag2" 和 "tag3" 时,我们有一组 3 个,或者只有一组 2 个,当文章有标签 "tag1"、"tag2" 和 "tag4".
- 然后只选择那些成员数量与我们所需的标签数组中指定的数量相同的组。
可能有更好的方法来实现您想要的,但这确实是我目前能想到的唯一解决方案。