如何在Postgresql中查找带有任何预定义标记的帖子

如何在Postgresql中查找带有任何预定义标记的帖子,postgresql,Postgresql,我有以下结构的posts表: | id | score | title | tags | ------------------------------------------------- | 1 | 42 | Travel | <uk><travel><passport> | 对于每个博客文章,我想找到相关的文章,用与当前页面相对应的任何标签进行标记,在我的例子中:,或。然后,按分数排序结果,将其限制为5

我有以下结构的posts表:

| 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)) );