不区分大小写的Postgres查询包含

时间:2016-12-01 12:54:13

标签: postgresql

我的记录包含这样的标记数组:

   id   |                     title                     |       tags
--------+-----------------------------------------------+----------------------
 124009 | bridge photo                                  | {bridge,photo,Colors}
 124018 | Zoom 5                                        | {Recorder,zoom}
 123570 | Sint et                                       | {Reiciendis,praesentium}
 119479 | Architecto consectetur                        | {quia}

我使用以下SQL查询按标记获取特定记录(&#39;桥&#39;,&#39;照片&#39;,&#39;颜色&#39;):< / p>

SELECT  "listings".* FROM "listings" WHERE (tags @> ARRAY['bridge', 'photo', 'Colors']::varchar[]) ORDER BY "listings"."id" ASC LIMIT $1  [["LIMIT", 1]]

这将返回此表中的第一条记录。

这个问题是我有混合类型的情况,如果我搜索:bridgephotocolors,我希望这会返回相同的结果。基本上我需要使这个搜索不区分大小写,但无法找到Postgres的方法。

这是我尝试过的SQL查询,它会抛出错误:

SELECT  "listings".* FROM "listings" WHERE (LOWER(tags) @> ARRAY['bridge', 'photo', 'colors']::varchar[]) ORDER BY "listings"."id" ASC LIMIT $1

这是错误:

  

PG :: UndefinedFunction:ERROR:函数lower(字符变化[])不存在
      提示:没有函数匹配给定的名称和参数类型。您可能需要添加显式类型转换。

2 个答案:

答案 0 :(得分:5)

您可以通过以下方式将文本数组元素转换为小写:

select lower(tags::text)::text[]
from listings;

          lower           
--------------------------
 {bridge,photo,colors}
 {recorder,zoom}
 {reiciendis,praesentium}
 {quia}
(4 rows)

在您的查询中使用此项:

SELECT * 
FROM listings
WHERE lower(tags::text)::text[] @> ARRAY['bridge', 'photo', 'colors'] 
ORDER BY id ASC;

   id   |    title     |         tags          
--------+--------------+-----------------------
 124009 | bridge photo | {bridge,photo,Colors}
(1 row) 

答案 1 :(得分:3)

您无法直接将LOWER()应用于数组,但您可以解压缩数组,将其应用于每个元素,并在完成后重新组合:

... WHERE ARRAY(SELECT LOWER(UNNEST(tags))) @> ARRAY['bridge', 'photo', 'colors']

您也可以安装citext (case-insensitive text) module;如果您将listings.tags声明为citext[]类型,则您的查询应按原样运行。