PR

GINを使った全文検索

 次に,いよいよGINによる全文検索を試してみよう。ここでは,テーブルの各行に,ドキュメントに含まれる単語の集合を配列として登録し,そこに含まれる単語を検索するものとする。

 同様にPostgreSQLでテキストの全文検索を実現するものにtsearch2というcontribモジュール(PostgreSQLのソースコードに付属するが,デフォルトではインストールされないソフトウェア)があるが,残念ながら現状では日本語が使用できない。

 つまり,GINは日本人にとって,標準のPostgreSQLだけで全文検索を実現できるはじめてのソリューションということになる。

 以下,GINによる全文検索を実現するためのステップを追っていこう。ここでは,テスト用のテキストとして,本稿の最初の方の,

GINは,"Generalized Inverted Index"の略で,日本語では「汎用転置索引」となる。GINはBtree同様,PostgreSQLのインデックスタイプの一つである。

GINを使うと,文章中に出現する単語毎にインデックスを作成し,ある単語が含まれるドキュメントを高速に検索するようなことが可能になる。

の部分を使用する。最初の段落でテーブルの1行,次の段落で2行目とする。

1) テストデータを単語毎に区切る。日本語は膠着語であり,英語のように単語の区切り目はすぐにはわからない。そこで,前処理をほどこして単語の区切りを明確にする。ここでは,kakasiを使って単語を空白で区切る。もちろんkakasiでなくても,chasenやMeCabを使ってもよい。具体的な手順は以下のようになる。

$ kakasi -w < 1行目のテキストファイル > 出力先ファイル名

 kakasiが手元にない場合は,とりあえず手動で単語を区切って間に合わせてもよい。テストにはそれで十分だ。結果はたとえば以下のようになる。

GIN は , "Generalized Inverted Index" の 略 で , 日本語 では 「 汎用 転置 索引 」 となる . GIN は Btree 同様 , PostgreSQL の インデックスタイプ の 一つ である .

2) 空白区切りのテキストを配列に変換する。これはPostgreSQLの組み込み関数string_to_arrayを使うと簡単だ。string_to_arrayは2つの引数を持ち,第一引数は処理したいテキスト,第二引数は区切り記号に使う文字だ。ここではもちろん空白を指定する。

3) 以上から,実際にテキストを登録するためのINSERT文は以下のようになる。

INSERT INTO t2 VALUES(string_to_array('GIN は , "Generalized Inverted Index" の 略 で , 日本語 では 「 汎用 転置 索引 」 となる 。 GIN は Btree 同様 , PostgreSQL の インデックスタイプ の 一つ である .', ' '));
INSERT INTO t2 VALUES(string_to_array('GIN を 使う と , 文章中 に 出現 する 単語 毎に インデックス を 作成 し , ある 単語 が 含ま れる ドキュメント を 高速 に 検索 するようなことが 可能に なる .', ' '));

後はGINインデックスを作成すればよい。

CREATE INDEX t2index ON t2 USING GIN(t);

実際に検索してみよう。

test=# SELECT * FROM t2 WHERE ARRAY['日本語'] ~ t;
t {GIN,は,,,"\"Generalized",Inverted,"Index\"",の,略,で,,,日本語,では,「,汎用,転置,索引,」,となる,.,GIN,は,Btree,同様,,,PostgreSQL,の,インデックスタイプ,の,一つ,である,.}
(1 row)

 このように,「日本語」が含まれている行が検索できた。