# Postgres 全文搜索的自定义词典

**URL:** https://meta.discourse.org/t/custom-dictionary-for-postgres-fulltext-search/153095
**Category:** Feature
**Created:** [2020 年5 月 28 日 12:51 UTC](https://meta.discourse.org/t/custom-dictionary-for-postgres-fulltext-search/153095 "2020-05-28T12:51:18Z")
**Posts on this page:** 2
**Page:** 1

<div class="post-metadata">

### Author: ![danekhollas](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/danekhollas/32/79637_2.png) [@danekhollas](https://meta.discourse.org/u/danekhollas)
#### Post date: [2020 年5 月 28 日 12:51 UTC](https://meta.discourse.org/t/custom-dictionary-for-postgres-fulltext-search/153095/1 "2020-05-28T12:51:18Z")

</div>

所以，下面讲讲我在提升捷克语论坛实例搜索功能方面的探索之旅。

不幸的是，当前的 PostgreSQL（12）并没有内置的捷克语词典。捷克语有 7 种变格形式（即名词根据上下文可以有 7 种不同的形式），因此可以想象，我们的搜索效果相当差。

我摸索出了如何在 Docker 实例中添加词典并使其生效（详见下文），但即使重新索引后，搜索仍然无法正常工作。原来，Discourse 是根据 `default_locale` 设置来选择词典的，并且只为那些随 PostgreSQL 自带的语言选择对应词典；对于其他语言，它一律使用 `simple` 词典。

> <https://github.com/discourse/discourse/blob/8a3d9d70363bed7839dfa2349be1288e1f543df5/lib/search.rb#L42>

**恳请支持：能否增加一个站点设置项，允许指定自定义搜索词典？**  
我验证过，只要手动编辑 `lib/search.rb`，一切就能正常工作。

以下是我添加词典的步骤，基本上复现了以下链接中的操作：

> **[Instalace Fulltextu - Instalace PostgreSQL](https://postgres.cz/wiki/Instalace_PostgreSQL#Instalace_Fulltextu)**
>
> Poté by výstup z ladící funkce na řetězec 'Příliš žluťoučký kůň se napil žluté vody' měl být následující:

以及：

> **[GitHub - tjelen/postgres-tsearch-czech: Postgres docker image with Czech full text search...](https://github.com/tjelen/postgres-tsearch-czech)**
>
> Postgres docker image with Czech full text search dictionaries

```bash
sudo ./launcher enter app
# 以下内容也应添加到 container/app.yml 中，以便在每次容器重建时执行
curl -L https://github.com/freaz/docker-postgres-czech-unaccent/raw/master/czech_unaccent.tar.gz | tar -xzC /tmp/ && mv /tmp/fulltext_dicts/czech* /usr/share/postgresql/1?/tsearch_data/
sudo -u postgres psql discourse
CREATE TEXT SEARCH DICTIONARY czech
   (template=ispell, dictfile = czech_unaccent, afffile=czech_unaccent, stopwords=czech_unaccent);
CREATE TEXT SEARCH CONFIGURATION czech (copy=english);
ALTER TEXT SEARCH CONFIGURATION czech
  ALTER MAPPING FOR word, asciiword WITH cspell, simple;
# 验证
\dF
# 测试
select * from ts_debug('czech_unaccent','Prilis zlutoucky kun se napil zlute vody');
Ctrl-D
rake search:reindex
Ctrl-D
# 在 containers/app.yml 中设置
db_default_text_search_config: "public.czech"
# 重建

```

还有一个关于重音符号的陷阱。上述方法下载的是不带重音符号的词典，因此它仅在“搜索时忽略重音”设置开启时才能正常工作。如果你希望搜索时保留重音符号，则应从 [https://postgres.cz/data/czech.tar.gz](https://postgres.cz/data/czech.tar.gz) 下载词典。

我认为这个陷阱同样适用于其他默认支持 Postgres 的语言。☹ 如果你去掉了重音符号，实际上就等同于关闭了该语言中那些包含重音字符单词的词干提取功能。因此，对于这类语言，是否应该启用“忽略重音”这一功能，目前还并不明确。

---

<div class="post-metadata">

### Author: ![danekhollas](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/danekhollas/32/79637_2.png) [@danekhollas](https://meta.discourse.org/u/danekhollas)
#### Post date: [2020 年6 月 22 日 11:49 UTC](https://meta.discourse.org/t/custom-dictionary-for-postgres-fulltext-search/153095/2 "2020-06-22T11:49:00Z")

</div>

> [@danekhollas](#):
>
> **拜托了，能否增加一个站点设置，用于指定自定义搜索词典？**  
> 我验证过，手动编辑 `lib/search.rb` 后一切都能正常工作。

@sam，您是否愿意接受针对上述内容的 PR？

或者，我们可以修改 Docker 基础镜像，默认包含更多 Postgres 搜索词典，但这会困难得多。
