F.29. pg_trgm

pg_trgmモジュールは、類似文字列の高速検索をサポートするインデックス演算子クラスだけではなく、trigram一致に基くテキスト類似度の決定に関する関数と演算子も提供します。

F.29.1. Trigram (またはTrigraph)の概念

trigramは文字列から3つの連続する文字を取り出したグループです。 共有するtrigramの個数を数えることで、2つの文字列の類似度を測定することができます。 この単純な考えが、多くの自然言語における単語の類似度を測定する際に非常に効率的であることが判明しています。

注意: 文字列内に含まれるtrigram集合を決める際、文字列の前に2つの空白、後に1つの空白が付いているものとみなされます。 例えば、"cat"という文字列のtrigram集合は、" c"" ca""cat""at "です。

F.29.2. 関数と演算子

表 F-27. pg_trgm関数

関数戻り値説明
similarity(text, text)real2つの引数がどの程度似ているかを示す数値を返します。 結果はゼロ(2つの文字列にまったく類似度がないことを示す)から1(2つの文字列が同一であることを示す)までの範囲です。
show_trgm(text)text[]与えられた文字列内のすべてのtrigramからなる配列を返します (実際これはデバッグ時を除いて役に立つことはほぼありません)。
show_limit()real%演算子で使用される現在の類似度閾値を返します。 これは、例えば2つの単語それぞれでミススペルがあったとしても類似しているものとみなす、その2つの単語間の最低の類似度を設定します。
set_limit(real)real%演算子で使用される現在の類似度閾値を設定します。 閾値は0から1までの値でなければなりません(デフォルトは0.3です)。 渡された値と同じ値が返ります。

表 F-28. pg_trgm演算子

演算子戻り値説明
text % textboolean2つの引数がset_limitで設定された類似度閾値以上の類似度を持つ場合trueを返します。

F.29.3. インデックスサポート

pg_trgmモジュールは、テキスト列全体に非常に高速な類似度検索を行うためのインデックスを作成することができるように、GiSTおよびGINインデックス演算子クラスを提供します。 これらの演算子型は%類似度演算子をサポートします(そして、この他の演算子をサポートしません。ですので通常のB-Treeインデックスも必要になるかもしれません)。

例:

CREATE TABLE test_trgm (t text);
CREATE INDEX trgm_idx ON test_trgm USING gist (t gist_trgm_ops);
  

または

CREATE INDEX trgm_idx ON test_trgm USING gin (t gin_trgm_ops);
  

この段階で、テキスト列tに類似度検索で使用可能なインデックスがあります。 典型的な問い合わせを以下に示します。

SELECT t, similarity(t, 'word') AS sml
  FROM test_trgm
  WHERE t % 'word'
  ORDER BY sml DESC, t;
  

これはwordに十分似たテキスト列の値をすべて、類似度の高い順番に返します。 インデックスは非常に大規模なデータ群に対する高速操作を行うために使用されます。

GiSTまたはGINインデックスの選択は、他で説明されるGiSTとGINの相対的な性能特性に依存します。 まとめとしては、GINインデックスはGiSTインデックスより検索が高速ですが、構築または更新は低速です。 このためGINは静的なデータに、GiSTはよく更新されるデータに適しています。

F.29.4. テキスト検索の統合

Trigram一致は全文テキストインデックスと一緒に使用する時、非常に有用なツールです。 特に、全文検索機構では直接一致しない、ミススペルがある入力単語の認識を行うために役に立ちます。

第一段階は文書内で一意な単語からなる補助テーブルを生成することです。

CREATE TABLE words AS SELECT word FROM
        ts_stat('SELECT to_tsvector(''simple'', bodytext) FROM documents');
  

ここでdocumentsは、検索対象のbodytextテキストフィールドを持つテーブルです。 言語固有の設定を使用するのではなく、to_tsvector関数でsimple設定を使用する理由は、元の(語幹抽出されていない)単語のリストが欲しいためです。

次にword列にtrigramインデックスを作成します。

CREATE INDEX words_idx ON words USING gin(word gin_trgm_ops);
  

これで、上の例に似たSELECT問い合わせを使用して、ユーザの検索語内でミススペルのある単語を提示できるようになります。 有用な追加された試験は、選択された単語の長さがミススペルのある単語の長さとほぼ同じになることを要求するものです。

注意: wordsテーブルは別に生成された静的なテーブルですので、文書群の更新に合理的に追従できるよう定期的に再生成する必要があります。 正確に最新状態を維持する必要性は通常ありません。

F.29.5. 参考

GiST開発サイト http://www.sai.msu.su/~megera/postgres/gist/

Tsearch2開発サイト http://www.sai.msu.su/~megera/postgres/gist/tsearch/V2/

F.29.6. 作者

Oleg Bartunov , Moscow, Moscow University, Russia

Teodor Sigaev , Moscow, Delta-Soft Ltd.,Russia

文書作成: Christopher Kings-Lynne

本モジュールはロシアモスクワのDelta-Soft Ltd.による後援です。