PostgreSQLの全文検索の機能(to_tsvector/to_tsquery)は、テキスト検索設定(configuration)・辞書(dictionary)・パーサ(parser)・テンプレート(template)という4種類のオブジェクトを組み合わせて動作する。それぞれの一覧を確認するpsqlメタコマンドが用意されている。

\dFコマンドでテキスト検索設定の一覧を確認する

to_tsvector('設定名', 文字列)の第1引数に指定できる設定の一覧は\dFで確認する。

testdb=# \dF
               List of text search configurations
   Schema   |    Name    |              Description
------------+------------+---------------------------------------
 pg_catalog | arabic     | configuration for arabic language
 pg_catalog | armenian   | configuration for armenian language
 ...
 pg_catalog | english    | configuration for english language
 ...
 pg_catalog | simple     | simple configuration
 ...
(29 rows)

デフォルトでは主要な自然言語ごとの設定と、言語非依存のsimple設定がインストールされている。

\dF+で設定の内訳を確認する

+を付けると、その設定がトークンの種類ごとにどの辞書を使うかが一覧表示される。

testdb=# \dF+ english
Text search configuration "pg_catalog.english"
Parser: "pg_catalog.default"
      Token      | Dictionaries
-----------------+--------------
 asciihword      | english_stem
 asciiword       | english_stem
 email           | simple
 ...
 word            | english_stem

word(通常の単語)にはenglish_stem辞書が使われ、emailurlのようなトークンには言語に依存しないsimple辞書が使われる。

simpleとenglishの違いを実際に確認する

simple設定は単語を小文字化するだけで語幹処理(ステミング)をしない。english設定はenglish_stem辞書により語形変化を正規化する。

testdb=# SELECT to_tsvector('english', 'The quick brown foxes are jumping');
             to_tsvector
--------------------------------------
 'brown':3 'fox':4 'jump':6 'quick':2

testdb=# SELECT to_tsvector('simple', 'The quick brown foxes are jumping');
                       to_tsvector
-----------------------------------------------------------
 'are':5 'brown':3 'foxes':4 'jumping':6 'quick':2 'the':1

english設定ではfoxesfoxに、jumpingjumpに正規化され、theareのようなストップワードが除去されている。simple設定ではどちらも行われず、単語がそのままの形でトークン化される。

\dFdコマンドで辞書一覧を確認する

個別の辞書一覧は\dFdで確認する。

testdb=# \dFd
                             List of text search dictionaries
   Schema   |      Name       |                        Description
------------+-----------------+-----------------------------------------------------------
 pg_catalog | english_stem    | snowball stemmer for english language
 ...
 pg_catalog | simple          | simple dictionary: just lower case and check for stopword
 ...
(29 rows)

english_stemのような_stemで終わる辞書は、Snowballアルゴリズムによる語幹処理を行う辞書である。

\dFpコマンドでパーサ一覧を確認する

文字列をトークンに分割するパーサの一覧は\dFpで確認する。

testdb=# \dFp
        List of text search parsers
   Schema   |  Name   |     Description
------------+---------+---------------------
 pg_catalog | default | default word parser
(1 row)

標準ではdefaultパーサだけが用意されている。独自の分割ルールが必要な場合は、拡張機能でパーサを追加できる。

\dFtコマンドでテンプレート一覧を確認する

辞書は「テンプレート+パラメータ」の組み合わせで作られる。テンプレート自体の一覧は\dFtで確認する。

testdb=# \dFt
                           List of text search templates
   Schema   |   Name    |                        Description
------------+-----------+-----------------------------------------------------------
 pg_catalog | ispell    | ispell dictionary
 pg_catalog | simple    | simple dictionary: just lower case and check for stopword
 pg_catalog | snowball  | snowball stemmer
 pg_catalog | synonym   | synonym dictionary: replace word by its synonym
 pg_catalog | thesaurus | thesaurus dictionary: phrase by phrase substitution
(5 rows)

english_stemのような個別言語の辞書は、snowballテンプレートにlanguage = 'english'パラメータを与えて作られている。同義語辞書がほしい場合はsynonymテンプレートを、独自の言い換えルールがほしい場合はthesaurusテンプレートを使う。

設定・辞書・パーサ・テンプレートの関係

4つのオブジェクトの関係は以下のようになる。

graph LR
  A[テキスト検索設定 dF] -->|使用する| B[パーサ dFp]
  A -->|トークン種別ごとに使用する| C[辞書 dFd]
  C -->|元になる| D[テンプレート dFt]

パーサが文字列をトークンに分割し、設定がトークンの種類ごとに使う辞書を決め、辞書がテンプレートに基づいて実際の正規化処理をする。全文検索の挙動が意図と異なる場合、まず\dF+でどの辞書が使われているかを確認するところから調査するとよい。

参考