PostgreSQL不区分大小写的GIN索引?

whlutmcx  于 2023-06-05  发布在  PostgreSQL
关注(0)|答案(1)|浏览(171)

当我们有单个字符串列时,我们可以使用upper()create index on tab(upper(col))构建一个基于函数的索引,当查询是select * from tab where upper(col) = ?时,它将使用该索引。好处是,当数据被检索时,数据保持在原始混合大小写,但查找不区分大小写。
当col是text[]类型时,我们可以使用GIN create index tab(col) using GIN(col)创建一个反向索引,然后select * from tab where col && ?查看参数数组与col数组是否重叠。
但如果我也想不区分大小写呢?当然,我可以将col规范化为所有大写,但这样会丢失原始数据。或者,如果我有两次列,作为标准化和原始,它可以工作。
我有一个主意,怎么样:

mydb=> create table tab(col text[]);
CREATE TABLE
mydb=> insert into tab values ('{Ay,bee,Cee}'::text[]);
INSERT 0 1
mydb=> select * from tab;
     col
--------------
 {Ay,bee,Cee}
(1 row)

mydb => select *, (select array_agg(upper(n)) from unnest(col) as n) from tab;
     col      |  array_agg
--------------+--------------
 {Ay,bee,Cee} | {AY,BEE,CEE}
(1 row)

mydb=> alter table tab add column norm text[] generated always as (select array_agg(upper(n)) from unnest(col) as n);
ERROR:  syntax error at or near "select"
LINE 1: ...e tab add column norm text[] generated always as (select arr...
                                                             ^

如果这样做成功了,我可能会在norm列上创建GIN索引。但可惜,它没有。还有别的解决办法吗

mlnl4t2r

mlnl4t2r1#

你需要将你的子查询封装到一个helper函数中:

create or replace function upper_array(text[]) returns text[] language sql as $$
   select array_agg(upper(unnest)) from unnest($1)
$$ immutable parallel safe;

然后,而不是添加一个需要额外空间的生成列,我可能只是直接在函数上定义索引:

create index on tab using gin (upper_array(col));

相关问题