如何在Postgresql中查找带有任何预定义标记的帖子
我有以下结构的posts表:如何在Postgresql中查找带有任何预定义标记的帖子,postgresql,Postgresql,我有以下结构的posts表: | id | score | title | tags | ------------------------------------------------- | 1 | 42 | Travel | <uk><travel><passport> | 对于每个博客文章,我想找到相关的文章,用与当前页面相对应的任何标签进行标记,在我的例子中:,或。然后,按分数排序结果,将其限制为5
| id | score | title | tags |
-------------------------------------------------
| 1 | 42 | Travel | <uk><travel><passport> |
对于每个博客文章,我想找到相关的文章,用与当前页面相对应的任何标签进行标记,在我的例子中:,或。然后,按分数排序结果,将其限制为5项,并将其显示给用户
这是我到目前为止提出的代码,但它似乎只得到查询中第一个标记的结果
编辑
在@Mike Organek的评论之后,我改变了这个查询,它按照我最初的预期工作
with tags_string (tag) as (
select unnest(string_to_array('<uk><travel><passport>', '>'))
)
select *
from
(
select distinct *
from posts
cross join tags_string
cross join lateral
(select
position(tag in tags) > 0 as match_found
) m
where m.match_found and tag <> ''
) t
order by t.score desc
limit 5;
我会将标签转换为数组,然后使用数组运算符查找相关帖子:
select id, title, score, tags
from posts
where string_to_array(trim(both '<>' from replace(tags, '><', ',')), ',') @> array['uk', 'travel', 'passport']
order by score
limit 5
如果需要,您甚至可以为此创建索引:
create index on posts using gin ( (tags_array(tags)) );
在任意一个尖括号上拆分将创建一个空字符串作为结果数组的元素。使用右侧的空字符串和左侧的非空文本执行~始终返回true。我看不出您的查询如何能够像编写的那样工作。@MikeOrganekThanks,我重写查询是为了检查字符串是否为非空,并使用position而不是~now,因为如果标记存储为正确的数组或jsonb列,则expectedIt的工作会容易得多。如果不在最里面的子查询中进行聚合,这种格式将是一场噩梦。您是否打算将sumtags~tag::int作为找到的匹配项的计数?我知道你换了位置,但问题应该是一样的
create function tags_array(p_input text)
returns text[]
as
$$
select string_to_array(trim(both '<>' from replace(p_input, '><', ',')), ',');
$$
language sql
immutable;
select id, title, score, tags
from posts
where tags_array(tags) @> array['uk', 'travel', 'passport']
order by score
limit 5
create index on posts using gin ( (tags_array(tags)) );