以前,部屋のファイルサーバのファイルを全文検索するために,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));
としているが,これだとtsearch2のnormalizationの影響で,キーワードによってはヒットしない場合があり得る. 実用上は,こうしたほうが良さそうだ.
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)); →○.ヒットする
普通,「oracle」を検索したい人が「oracl」とキーワード指定することは無いので,oracleというキーワードでもヒットするような結果を得るには,to_tsquery()をかましてキーワードもnormalizationしなければ.

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


© 2024 KMIソフトウェア