日本語正規化+pg_trgm

組み合わせ方法

とりあえず、pg_trgmと日本語正規化の組み合わせを検証してみた。
仕掛けはそんなに難しい話ではなく、日本語の正規化を行う関数(pg_ntext_normalize)をSQL関数として公開し、その関数を使って、pg_trgmインデクスを張る列を関数インデクスとして実装するだけ。

foo=# CREATE INDEX idx_ntext ON book_ntext USING gin ((pg_ntext_normalize(data)::text) gin_trgm_ops);

クエリはこの形式に合わせて書かなきゃいけないので、やや長くなるが仕方がない。

検証結果

比較のため、普通のテキスト型+pg_trgmでの検索例も示す。

テキトーにテキストをロードしておく。今はこんな感じのテキストが入っている。

foo=# SELECT * FROM book_text;
 id  |                                             data                                             
-----+----------------------------------------------------------------------------------------------
  91 | 私は今まで一度もエヴァンゲリオンという作品を見たことがない。
  92 | PostgreSQL(ポストグレエスキューエル)はオープンソースのデータベースシステムである。
  93 | MySQLとPostgreSQLを使っている人は多い。
  94 | 劇場版エヴァンゲリヲンを観ることをエヴァヲタの人に勧められた。
  95 | ティーガーとパンターはドイツの名戦車だ。
  96 | ガルパンとはガールズ&パンツァーの略称である。ストパンはストライクウィッチーズの愛称である。
  97 | ぎゃーていぎゃーていはらぎゃーてい はらそうぎゃーてい ぼちそわかはんにゃしんきょう
  98 | ナイアーラトテップとニャルラホトテプは同じ神をさしている。
  99 | 昨日はみそラーメンを食べた。今日はミソらーめんを食べた。
 100 | 江ノ島のねこは人懐っこい。
 101 | ちどり公園のネコはやや警戒心が強いようだ。
 102 | イタリアのヴェネチアでカルボナーラを食べた。
 103 | ワタシハ、キョウカゾクトイッショニ、エヴァンゲリヲンゲキジョウバンヲミニイッタ。
 104 | 横シューティング御三家はダライアス、グラディウス、アールタイプだ。
 105 | 今でもポストグレスにはヴァキュームが必須だと誤解されている。
 106 | 自分のPCが「シャバドゥビタッチヘンシーン」とか喋ったら、さぞかしウザいことだろう。
 107 | 私は「ニンニクマシマシカラメ」と呪文を唱えた。周囲から「ギルティ!」と声が上がる。
(17 rows)

まず、カタカナ正規化の例

foo=# SELECT id, data FROM book_text WHERE data LIKE '%エバ%';
 id | data 
----+------
(0 rows)

foo=# SELECT id, data FROM book_ntext WHERE pg_ntext_normalize(data)::text LIKE pg_ntext_normalize('%エバ%')::text;
 id  |                              data                              
-----+----------------------------------------------------------------
  91 | 私は今まで一度もエヴァンゲリオンという作品を見たことがない。
  94 | 劇場版エヴァンゲリヲンを観ることをエヴァヲタの人に勧められた。
 103 | ワタシハ、キョウカゾクトイッショニ、エヴァンゲリヲンゲキジョウバンヲミニイッタ。
(3 rows)

次にひらがな/カタカナ正規化の例

foo=# SELECT id, data FROM book_text WHERE data LIKE '%ねこ%';
 id  |            data            
-----+----------------------------
 100 | 江ノ島のねこは人懐っこい。
(1 row)

foo=# SELECT id, data FROM book_ntext WHERE pg_ntext_normalize(data)::text LIKE pg_ntext_normalize('%ねこ%')::text;
 id  |                    data                    
-----+--------------------------------------------
 100 | 江ノ島のねこは人懐っこい。
 101 | ちどり公園のネコはやや警戒心が強いようだ。
(2 rows)

全角/半角英字正規化の例

foo=# SELECT id, data FROM book_text WHERE data LIKE '%PostgreSQL%';
 id |                                        data                                        
----+------------------------------------------------------------------------------------
 92 | PostgreSQL(ポストグレエスキューエル)はオープンソースのデータベースシステムである。
(1 row)

foo=# SELECT id, data FROM book_ntext WHERE pg_ntext_normalize(data)::text LIKE pg_ntext_normalize('%PostgreSQL%')::text;
 id |                                        data                                        
----+------------------------------------------------------------------------------------
 92 | PostgreSQL(ポストグレエスキューエル)はオープンソースのデータベースシステムである。
 93 | MySQLとPostgreSQLを使っている人は多い。
(2 rows)

一応、全文検索との連動も出来るなら、それなりに実用的に使えるかもしれない(性能の問題はあるにせよ)。
さて、次は近似検索とtextsearch_ja連動かな・・・