textsearch-ja ホームページへようこそ


形態素解析を使用した、組み込み型の日本語全文検索です。

この textsearch-ja プロジェクトは PostgreSQL コミュニティによる pgFoundry の中のプロジェクトです。

Here is an English page.

概要

日本語テキストの全文検索を行います。 PostgreSQL 8.3 で追加された組み込みテキスト検索を拡張するため、 英語文書の検索と同様の方法で、日本語文書を検索することができます。 検索は形態素解析を利用した単語単位で行われます。 形態素解析には MeCab を使用しています。

利点として、GIN または GiST インデックスをベースにしているため、全文検索用のインデックスがリカバリ可能であることが挙げられます。 また、既に tsearch2 に対応している欧米言語を対象とした製品を大きく改変することなく、日本語対応できる強みがあります。

インストール

依存関係

以下の外部プロジェクトに依存しています。

MeCab

Windows 版のインストーラを使う場合、辞書の文字コードの選択 で UTF-8 を選んでください。 mecab-dict-index で辞書を再編成することもできます。 詳しくは MeCab のマニュアルを参照してください。

テキスト検索機能

インストールすると、pg_catalog.japanese という名前のテキスト検索設定が登録されます。 以下の形式で使用します。

入力テキストは、まず、後述の ja_normalize() 関数を使用して正規化されます。 正規化後の文字列に対して、形態素解析で単語を分割してインデックスを張ります。

サーバエンコーディングと、mecab のエンコーディングを一致させる必要があります。 プラットホームによっては、mecab 辞書の再コンパイルが必要になるかもしれません。

インデックス (tsvector, tsquery)

textsearch では、関数インデックスを使用して直接検索する方式と、 追加した補助カラムをキーとして検索する方式があります。 詳しくはドキュメント Full Text Search/Creating Indexes を参照してください。 補助カラムの自動更新は、tsvector_update_trigger に任せることもできます。

=# CREATE TABLE test (id serial, t text);
=# COPY test(t) FROM '...';
=# CREATE INDEX idx ON test USING gin(to_tsvector('japanese', t));
=# ANALYZE;
=# EXPLAIN SELECT * FROM test WHERE to_tsvector('japanese', t) @@ to_tsquery('japanese', 'リレーショナルデータベース');
                                                      QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------
 Index Scan using idx on test  (cost=0.00..8.27 rows=1 width=248)
   Index Cond: (to_tsvector('japanese'::regconfig, t) @@ '''リレーショナル'' & ''データベース'''::tsquery)
(2 rows)

検索結果の強調 (ts_headline)

ts_headline() に対応しており、一致した箇所を切り出して強調表示できます。
=# \d document
                         Table "public.document"
 Column |   Type   |                      Modifiers
--------+----------+-------------------------------------------------------
 id     | integer  | not null default nextval('document_id_seq'::regclass)
 body   | text     |
 tsv    | tsvector |
Indexes:
    "document_pkey" PRIMARY KEY, btree (id)
    "document_tsv_index" gin (tsv)
Triggers:
    tsv_trigger BEFORE INSERT OR UPDATE ON document FOR EACH ROW EXECUTE PROCEDURE
      tsvector_update_trigger('tsv', 'pg_catalog.japanese', 'body')

=# SELECT id, ts_rank_cd(tsv, query) AS rank, ts_headline('japanese', body, query)
     FROM document, to_tsquery('japanese', 'リーフページ') AS query
    WHERE tsv @@ query ORDER BY rank DESC;
 id |   rank   |                                                                 ts_headline
----+----------+----------------------------------------------------------------------------------------------------------------------------------------------
  3 | 0.108333 | <b>ページ</b>中で隣接しているキーである。これは非ユニークキーに対しては動作しない ( たとえば、いくつかの<b>リーフ</b><b>ページ</b>にまたがっ
  2 |     0.01 | <b>ページ</b>を指しているはずである。同じ方法で、つまりヒープタプルへのリンクを調査することで、<b>リーフ</b>レベルにある複数の item
(2 rows)

解析結果の表示 (ts_debug)

=# SELECT * FROM ts_debug('japanese', '日本語とEnglishがmixedな文も解析OKです。');
   alias   |    description    |  token  |  dictionaries  |  dictionary  |  lexemes
-----------+-------------------+---------+----------------+--------------+-----------
 word      | Word, all letters | 日本語  | {simple}       | simple       | {日本語}
 blank     | Space symbols     | と      | {}             |              |
 blank     | Space symbols     |         | {}             |              |
 asciiword | Word, all ASCII   | English | {english_stem} | english_stem | {english}
 blank     | Space symbols     |         | {}             |              |
 blank     | Space symbols     | が      | {}             |              |
 blank     | Space symbols     |         | {}             |              |
 asciiword | Word, all ASCII   | mixed   | {english_stem} | english_stem | {mix}
 blank     | Space symbols     |         | {}             |              |
 blank     | Space symbols     | な      | {}             |              |
 word      | Word, all letters | 文      | {simple}       | simple       | {文}
 blank     | Space symbols     | も      | {}             |              |
 word      | Word, all letters | 解析    | {simple}       | simple       | {解析}
 blank     | Space symbols     |         | {}             |              |
 asciiword | Word, all ASCII   | OK      | {english_stem} | english_stem | {ok}
 blank     | Space symbols     |         | {}             |              |
 blank     | Space symbols     | です    | {}             |              |
 blank     | Space symbols     | 。      | {}             |              |
(18 rows)

類義語 (synonym)

類義語辞書を使用できます。 $PGDATA/share/tsearch_data/japanese.syn というテキストファイルを用意します。 文字エンコーディングは UTF-8 でなければなりません。

 バキューム	vacuum
 ポスグレ	pgsql
類義語辞書は、以下のSQLを使って登録します。
-- Install japanese synonym dictionary
CREATE TEXT SEARCH DICTIONARY japanese_syn (
    TEMPLATE = synonym,
    SYNONYMS = japanese
);
ALTER TEXT SEARCH CONFIGURATION japanese
    ALTER MAPPING FOR word, hword_part, hword WITH japanese_syn, simple;

類義語は変換して処理されるため、表記に揺れがあっても検索や強調ができます。

=# SELECT ts_headline('japanese', 'autovacuumを使えばバキュームも手間要らず',  to_tsquery('japanese', 'VACUUM'));
                   ts_headline
--------------------------------------------------
 autovacuum を使えば<b>バキューム</b>も手間要らず
(1 row)

同様に、$PGDATA/share/tsearch_data/english.syn を用意すれば、 英語の類義語辞書も同時に使用できます。 このとき、英語と日本語で必ずしも *.syn を分ける必要はありませんが、 英数字(半角)には必ず英語辞書が使われ、 日本語文字(全角)には必ず日本語辞書が使われるため、 分割したほうが若干変換速度が向上します。

-- Install english synonym dictionary
CREATE TEXT SEARCH DICTIONARY english_syn (
    TEMPLATE = synonym,
    SYNONYMS = english
);
ALTER TEXT SEARCH CONFIGURATION japanese
    ALTER MAPPING FOR asciiword, hword_asciipart, asciihword WITH english_syn, english_stem;

ストップワード (stop word)

現在、以下の品詞はストップワード(blank)とみなし、インデックス化していません。 不必要なインデックス・エントリを減らせるため、単純なスペース区切りによる分かち書きよりも効率が高まります。

実際には、類義語辞書と同じ方式で、textsearch 機能のストップワード辞書機能を使うことも可能です。 ただし、既に MeCab により単語区分が分かっているため、辞書よりも先に判定を行っています。 将来のバージョンでは、動作を選択可能にすることを考えています。

その他の検索用関数

Web検索互換クエリ (web_query)

textsearch は AND, OR, NOT 検索に &, |, ! を使用しています。 ウェブ検索で一般的に使用される制御演算子とは異なるため、検索フォームへの入力をそのまま条件に使用するには不便です。 関数 web_query() は、AND, OR, NOT 演算子として、スペース, OR (大文字), - を使用します。

=# SELECT to_tsquery('english', 'Relational Database');
ERROR:  syntax error in tsquery: "Relational Database"

=# SELECT to_tsquery('english', web_query('Relational Database'));
     to_tsquery
---------------------
 'relat' & 'databas'
(1 row)

注意: 現在、OR 演算子よりも AND 演算子のほうが結合順序が高いままです。 一般的なウェブ検索では、OR 演算子のほうが高いものが多いようです。

日本語解析機能

テキストを正規化する関数と、MeCab を直接利用する関数が登録されます。

テキストの正規化 (ja_normalize)

ja_normalize(text) は、入力された日本語テキストを正規化します。 大文字小文字は変換しません。
=# SELECT ja_normalize('カタカナは全角に、ABC123は半角に。ダクテンにも対応。');
                      ja_normalize
--------------------------------------------------------
 カタカナは全角に、 ABC123 は半角に。ダクテンにも対応。
(1 row)

分かち書き (ja_wakachi)

ja_wakachi(text) は、入力された日本語テキストを分かち書きします。 入力の正規化は行いません。
=# SELECT ja_wakachi('分かち書きも使用できます。スペースで区切られます。');
                          ja_wakachi
---------------------------------------------------------------
 分かち書き も 使用 でき ます 。 スペース で 区切ら れ ます 。
(1 row)

mecab による解析 (ja_analyze)

ja_analyze(text) は、入力された日本語テキストを mecab で解析した結果を返します。
=# SELECT * FROM ja_analyze('mecabを利用して形態素解析をします。');
  word  |  type  | subtype1 | subtype2 | subtype3 |  conjtype  | conjugation | basic  |    ruby    | pronounce
--------+--------+----------+----------+----------+------------+-------------+--------+------------+------------
 mecab  | 名詞   | 一般     |          |          |            |             | mecab  | mecab      | mecab
 を     | 助詞   | 格助詞   | 一般     |          |            |             | を     | ヲ         | ヲ
 利用   | 名詞   | サ変接続 |          |          |            |             | 利用   | リヨウ     | リヨー
 し     | 動詞   | 自立     |          |          | サ変・スル | 連用形      | する   | シ         | シ
 て     | 助詞   | 接続助詞 |          |          |            |             | て     | テ         | テ
 形態素 | 名詞   | 一般     |          |          |            |             | 形態素 | ケイタイソ | ケイタイソ
 解析   | 名詞   | サ変接続 |          |          |            |             | 解析   | カイセキ   | カイセキ
 を     | 助詞   | 格助詞   | 一般     |          |            |             | を     | ヲ         | ヲ
 し     | 動詞   | 自立     |          |          | サ変・スル | 連用形      | する   | シ         | シ
 ます   | 助動詞 |          |          |          | 特殊・マス | 基本形      | ます   | マス       | マス
 。     | 記号   | 句点     |          |          |            |             | 。     | 。         | 。
(11 rows)

TODO

ストップワード辞書に対応する
日本語版の辞書を用意する必要があります。
mecab のエンコーディングとサーバエンコーディングが異なる場合へ対処する
現在、一致していないと形態素解析の結果が異常になります。

関連リンク



Powered By GForge Collaborative Development Environment