ファイルサーバをPostgreSQL8.3で全文検索するというのを,相変わらず色々やっている.日本語の文書の場合,英数字が全角で書かれている場合があるが,検索したときは全角も半角も同じようにヒットして欲しい. つまり「Apache」で検索したときは,「Apache」も「Apache」も両方ヒットしなければ困る. これを実現するためには,文書をインデックス化するときに英字を半角変換すればよい. そのために, 今 は以下のような方法を採っている. インデックス作成 create or replace function zenkakuToHankaku( in i_zenstr text) returns text immutable as $$ declare v_hanstr text; begin v_hanstr := translate(i_zenstr, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'); v_hanstr := translate(v_hanstr, 'abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz'); v_hanstr := translate(v_hanstr, '1234567890', '1234567890'); v_hanstr := translate(v_hanstr, ' ', ' '); return v_hanstr; end $$ language plpgsql; CREATE INDEX file_item_z1 ON file_item USING gin (to_tsvector('english', wakachi(zenkakuToHankaku(contents)))); 検索 SELECT file_path FROM file_item, to_tsquery('pg_catalog.english', zenkakuToHankaku(?)) query WHERE query @@ to_tsvector('english',wakachi(zenkakuToHankaku(contents))); インデックス化の前処理Functionとして,zenkakuToHankaku()を作成し,これで半角変換を行っている. このFunctionは,「immutable」に指定しないと検索時にインデックスが効かなくなるので注意が必要. まぁFunctionインデックスみたいな用法なので,そういうものなのでしょう. 余談だが,PostgreSQL用全文検索関連ソフトウェア SRA OSSには,normalizeというまさにうってつけのC言語関数が公開されているが,しかしこれはEUC-JP用だった.orz 今回はUTF-8でやっているのでした. ...まぁ,これで一応目的は達成できてちゃんと動いているのだが,どうも間抜けな気がする. こういう汎用的な処理をわざわざFunctionを作って行っているというところに,違和感を感じる. それでマニュアルを見ると 12.6.2. Simple Dictionary The simple dictionary template operates by converting the input token to lower case and checking it against a file of stop words. また, 12.6. Dictionaries If no existing template is suitable, it is possible to create new ones; see the contrib/ area of the PostgreSQL distribution for examples. う〜む.そこまで手を染めるべきなのだろうか. |