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

时间:2015-02-20 11:31:30

标签: postgresql database-design indexing full-text-search case-insensitive

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

我发现这篇关于重音不敏感的帖子:
Does PostgreSQL support "accent insensitive" collations?

但是我们需要将它与不区分大小写结合起来。我们还需要使用索引,否则可能会影响性能。 有关大型数据库最佳方法的真实经验吗?

2 个答案:

答案 0 :(得分:5)

如果您需要"结合不区分大小写的",根据您的具体要求,有多种选择。

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

以参考答案中列出的函数f_unaccent()为基础:

CREATE INDEX users_lower_unaccent_name_idx ON users(lower(f_unaccent(name)));

然后:

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

您可以将lower()构建到函数f_unaccent()中,以获得类似f_lower_unaccent()的内容。

(特别是如果你需要进行模糊模式匹配)你可以使用上面函数构建的附加模块pg_trgm提供的三元组索引,它也支持{{1 }}。详细说明:

我在referenced answer添加了一条注释。

您可以使用其他模块citext

答案 1 :(得分:0)

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

FTS is naturally case-insensitive by default,

  

将令牌转换为lexemes。 lexeme是一个字符串,就像一个标记,但它已被标准化,以便使相同单词的不同形式相似。例如,规范化几乎总是包括将大写字母折叠为小写,并且通常涉及删除后缀(例如英语中的s或es)。

您可以使用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)

另见