以前,部屋のファイルサーバのファイルを全文検索するために,OracleSESの試用版を入れてみた.しかしOracle+Javaなのでメモリを食うし, そのページにも書いているように細かい点で気に入らないところがある. そしてそもそもお試し版だ.(確か正式版は数100万円するはず) そこで,自分で全文検索システムを作ることにした. エンジンはPostgreSQLのtsearch2を使う.また,ポスグレは8.3からはtsearch2が本体に内蔵されるようなので,8.3(まだベータだが)を使うことにした.
PostgreSQLの全文検索設定と,検索クエリーの作り方については, を参考にした.形態素解析にはmecabを使う. そしてファイルの内容をDBに登録するためのインデックサは,perlで自作した.また検索画面も,perlの自作CGI. 詳しくは以下のページに書いています. (1) 上記のページを見てハマってしまった箇所 (検索キーワードのnormalization)上記の記事では,検索クエリーをSELECT * FROM t1 WHERE 'foo' @@ to_tsvector('english',wakachi(t)); SELECT * FROM t1 WHERE to_tsquery('english','foo') @@ to_tsvector('english',wakachi(t)); 具体的には例えば,このようにenglishの設定で「oracle」という単語をインデックス化すると,「oracl」に変換されて格納される(normalization).この状態だと,以下の挙動になってしまう. SELECT * FROM t1 WHERE 'oracle' @@ to_tsvector('english',wakachi(t)); →×.ヒットしない SELECT * FROM t1 WHERE 'oracl' @@ to_tsvector ('english',wakachi(t)); →○.ヒットする englishではなく,simpleの設定でインデックス作成すれば,こういうnormalizationは発生しないので気にしなくても良さそうに思えるが,どうなのだろうか. 当初はtsearch2のことはあまり詳しく調べずに済まそうと思っていたが,こういうわけで結局公式サイトの英語と格闘する羽目になった...
(2) ヘッドラインの作成が遅い下図が検索結果画面の例だが,検索結果に対して
を表示している.
このヘッドラインの生成が遅い. 以下に検索SQLの実行計画を示すが,ヘッドラインが無い場合は1ミリ秒以下で検索終了しているのに,ヘッドラインを生成させると6.7秒もかかっている. もし可能ならば何とかしたいものだ. ヘッドラインが無い場合 ----- 実行計画 ----- Sort (cost=43.05..43.06 rows=5 width=107) (actual time=0.687..0.758 rows=27 loops=1) Sort Key: st_mtime Sort Method: quicksort Memory: 21kB -> Bitmap Heap Scan on file_item (cost=24.52..42.99 rows=5 width=107) (actual time=0.361..0.531 rows=27 loops=1) Recheck Cond: (to_tsvector('simple'::regconfig, wakachi(contents)) @@ '全文 & 検索'::tsquery) -> Bitmap Index Scan on file_item_z1 (cost=0.00..24.51 rows=5 width=0) (actual time=0.331..0.331 rows=27 loops=1) Index Cond: (to_tsvector('simple'::regconfig, wakachi(contents)) @@ '全文 & 検索'::tsquery) Total runtime: 0.919 ms ヘッドラインがある場合 ----- 実行計画 ----- Sort (cost=43.08..43.09 rows=5 width=647) (actual time=6737.722..6737.795 rows=27 loops=1) Sort Key: st_mtime Sort Method: quicksort Memory: 43kB -> Bitmap Heap Scan on file_item (cost=24.52..43.02 rows=5 width=647) (actual time=13.924..6737.147 rows=27 loops=1) Recheck Cond: (to_tsvector('simple'::regconfig, wakachi(contents)) @@ '全文 & 検索'::tsquery) -> Bitmap Index Scan on file_item_z1 (cost=0.00..24.51 rows=5 width=0) (actual time=0.378..0.378 rows=27 loops=1) Index Cond: (to_tsvector('simple'::regconfig, wakachi(contents)) @@ '全文 & 検索'::tsquery) Total runtime: 6738.106 ms |