PostgreSQL 重音 + 不区分大小写的搜索

PostgreSQL accent + case insensitive search

我正在寻找一种方法来支持不区分大小写 + 重音不区分搜索的良好性能。到目前为止,我们在使用 MSSql 服务器上没有问题,在 Oracle 上我们必须使用 OracleText,现在我们在 PostgreSQL 上需要它。

我已经找到了 this post,但我们需要将它与不区分大小写结合起来。我们还需要使用索引,否则性能可能会受到影响。 关于大型数据库的最佳方法的任何实际经验?

如果您需要“不区分大小写”,有多种选择,具体取决于您的具体要求。

也许最简单,使表达式索引不区分大小写。

基于参考答案中列出的函数 f_unaccent()

  • Does PostgreSQL support "accent insensitive" collations?
CREATE INDEX users_lower_unaccent_name_idx ON users(<b>lower(</b>f_unaccent(name)<b>)</b>);

然后:

SELECT *
FROM   users
WHERE  lower(f_unaccent(name)) = lower(f_unaccent('João'));

你可以将 lower() 构建到函数 f_unaccent() 中,以导出类似 f_lower_unaccent().

的东西

(特别是如果你无论如何都需要进行模糊模式匹配)你可以使用附加模块 pg_trgm 提供的三元组索引建立在上述功能之上,它还支持 ILIKE。详情:

  • LOWER LIKE vs iLIKE

我在 referenced answer 中添加了注释。

可以使用附加模块citext(但我宁愿避免它):

  • Deferrable, case-insensitive unique constraint

不区分大小写的全文搜索词典

FTS is naturally case-insensitive by default,

Converting tokens into lexemes. A lexeme is a string, just like a token, but it has been normalized so that different forms of the same word are made alike. For example, normalization almost always includes folding upper-case letters to lower-case, and often involves removal of suffixes (such as s or es in English).

您还可以使用 unaccent

定义自己的字典
CREATE EXTENSION unaccent;

CREATE TEXT SEARCH CONFIGURATION mydict ( COPY = simple );
ALTER TEXT SEARCH CONFIGURATION mydict
  ALTER MAPPING FOR hword, hword_part, word
  WITH unaccent, simple;

然后您可以使用功能索引对其进行索引,

-- Just some sample data...
CREATE TABLE myTable ( myCol )
  AS VALUES ('fóó bar baz'),('qux quz');

-- No index required, but feel free to create one
CREATE INDEX ON myTable
  USING GIST (to_tsvector('mydict', myCol));

现在可以很简单的查询了

SELECT *
FROM myTable
WHERE to_tsvector('mydict', myCol) @@ 'foo & bar'

    mycol    
-------------
 fóó bar baz
(1 row)

另见