在 postgres 中创建不区分大小写的 trigram-index 的正确方法是什么?

What is the correct way to create a case-insensitive trigram-index in postgres?

...这是我应该做的事吗?

根据我的简短测试,制作三元组索引并使用

进行搜索
where name like '%query%'

where name ilike '%query%'

看来我应该这样做,但令我惊讶的是我一直没能找到方法。

(我的测试数据相当均匀 - 150 万行由重复的 16 个条目组成。我可以想象这可能会影响结果。)

这是我预期的工作方式(注意 lower(name)):

create extension pg_trgm;

create table users(name text);

insert into users values('Barry');

create index "idx" on users using gin (lower(name) gin_trgm_ops);

select count(*) from users where (name like '%bar%');

但是这个returns0.

select count(*) from users where (name like '%Bar%');

select count(*) from users where (name ilike '%bar%');

工作,这让我相信索引中的三字母不是 lower()'。我是否误解了它的工作原理?那里不能调用lower吗?

我注意到这个

select show_trgm('Barry')

returns小写八卦:

{"  b"," ba",arr,bar,rry,"ry "}

所以我很困惑。

八卦肯定是小写的。

当您考虑如何使用三元组索引时,这个难题就迎刃而解了:它们充当过滤器,消除了大多数 non-matches,但允许误报结果(其中一个原因是它们不区分大小写)。这就是为什么总是需要重新检查以消除这些误报,这也是为什么您总是进行位图索引扫描的原因。

ILIKE 查询可能会比较慢,因为它有更多的结果,或者因为不区分大小写的比较需要更多的努力。