在创建索引期间“错误:文本搜索字典“unaccent”不存在?

Bal*_*aki 4 postgresql index index-tuning functions unaccent

我在 Mac OS X Yosemite 上运行 PostgreSQL 9.3。

我尝试创建一个非重音小写三元组索引。为了实现它,我这样做了:

mydb=# CREATE EXTENSION pg_trgm SCHEMA public VERSION "1.1"; 
       CREATE EXTENSION unaccent SCHEMA public; 
       ALTER FUNCTION unaccent(text) IMMUTABLE;
CREATE EXTENSION
CREATE EXTENSION
ALTER FUNCTION
Run Code Online (Sandbox Code Playgroud)

然后我尝试创建索引:

mydb=# CREATE INDEX author_label_hun_gin_trgm ON address 
       USING gin (public.unaccent(lower(label_hun)) gin_trgm_ops);
ERROR:  text search dictionary "unaccent" does not exist
Run Code Online (Sandbox Code Playgroud)

...并得到这个错误。如果我尝试列出可用的文本搜索词典,该unaccent词典似乎就在那里:

mydb=# \dFd
                             List of text search dictionaries
   Schema   |      Name       |                        Description                        
------------+-----------------+-----------------------------------------------------------
 pg_catalog | danish_stem     | snowball stemmer for danish language
 pg_catalog | dutch_stem      | snowball stemmer for dutch language
 pg_catalog | english_stem    | snowball stemmer for english language
 pg_catalog | finnish_stem    | snowball stemmer for finnish language
 pg_catalog | french_stem     | snowball stemmer for french language
 pg_catalog | german_stem     | snowball stemmer for german language
 pg_catalog | hungarian_stem  | snowball stemmer for hungarian language
 pg_catalog | italian_stem    | snowball stemmer for italian language
 pg_catalog | norwegian_stem  | snowball stemmer for norwegian language
 pg_catalog | portuguese_stem | snowball stemmer for portuguese language
 pg_catalog | romanian_stem   | snowball stemmer for romanian language
 pg_catalog | russian_stem    | snowball stemmer for russian language
 pg_catalog | simple          | simple dictionary: just lower case and check for stopword
 pg_catalog | spanish_stem    | snowball stemmer for spanish language
 pg_catalog | swedish_stem    | snowball stemmer for swedish language
 pg_catalog | turkish_stem    | snowball stemmer for turkish language
 public     | unaccent        | 
Run Code Online (Sandbox Code Playgroud)

知道这里有什么问题吗?

Erw*_*ter 7

我推荐使用这种替代方法来获取IMMUTABLE unaccent()函数:

CREATE OR REPLACE FUNCTION f_unaccent(text)
  RETURNS text AS
$func$
SELECT public.unaccent('public.unaccent', $1)  -- schema-qualify function and dictionary
$func$  LANGUAGE sql IMMUTABLE;
Run Code Online (Sandbox Code Playgroud)

将该函数用于表达式索引和所有查询。详细解释:

而且也没有改变原有的功能:

ALTER FUNCTION unaccent(text) IMMUTABLE;
Run Code Online (Sandbox Code Playgroud)

.. 这也解决了以下任何可能的问题search_path:您必须public.unaccent()在索引定义中进行模式限定这一事实表明public您的search_path.

然后,您的索引:

CREATE INDEX author_label_hun_gin_trgm ON address 
USING gin (f_unaccent(label_hun) gin_trgm_ops);
Run Code Online (Sandbox Code Playgroud)

我并没有包括lower()。您可以,但三元组索引支持开箱即用的不区分大小写的模式:

故障排除

如果您在同一个会话中以相同的方式运行所有这些,search_path并且在下一个报告时一个调用有效function ... does not exist,那么您的数据库中的某些内容已严重损坏。

首先确保您正在使用有效的search_path设置进行测试:

SHOW search_path
Run Code Online (Sandbox Code Playgroud)

此相关答案中的详细信息

如果您诊断出损坏,请切换到警报模式并采取所有必要步骤以避免数据丢失(例如在执行任何其他操作之前进行备份)。

系统表的索引损坏pg_proc可能是原因。要从shell重新索引所有系统表:

CREATE OR REPLACE FUNCTION f_unaccent(text)
  RETURNS text AS
$func$
SELECT public.unaccent('public.unaccent', $1)  -- schema-qualify function and dictionary
$func$  LANGUAGE sql IMMUTABLE;
Run Code Online (Sandbox Code Playgroud)