検証対象
・PostgreSQL GIN Index
http://www.postgresql.jp/document/pg836doc/html/gin.html
- PostgreSQLの転置インデックス
・Lucene
http://lucene.apache.org/
- Javaで書かれた全文検索エンジン
実績多数
今回使用したソース。
Senの辞書、Luceneのインデックス等は自分で作成してください。
fulltextsearch-sample.zip
調査データ
青空文庫(http://www.aozora.gr.jp/)のデータを取り込んでそれぞれ検証した。
テキストデータの行ごとにレコード、インデックス作成を行い。
それぞれ検証を行った。
対象レコードは約100万レコード
検証はローカルのPostgresql 8.4上で行った。
設定はデフォルト。
PostgreSQL GIN
CREATE TABLE gin_test_table
(
id integer NOT NULL,
original_text text, -- もともとのテキスト
array_text text[], -- 形態素解析を行ったものを格納
CONSTRAINT pk_test_table PRIMARY KEY (id)
)
というテーブルをつくり
GINインデックスをarray_textに張る。
CREATE INDEX gin_index
ON gin_test_table
USING gin
(array_text);
・データ件数:1162687件
select count(*) from gin_test_table
SQLでLIKE検索した場合約2分程度検索でかかる。
select count(*) from gin_test_table
where original_text like '%吾輩%'
※ キャッシュに乗ると2秒ほど
・GINインデックスを使用した場合
select count(*) from gin_test_table
where array_text && ARRAY['吾輩']
大体数十ms
◇ メリット
・導入が比較的簡単
- Postgresqlに検索テーブルを作成してIndexを張る
・DBFluteも使える
・APサーバを複数配置したとしてもDBで一元管理できる
・通常のSQLが使用できる
◇ デメリット
・分かち書きをしたものをARRAYのカラムに入れないといけないため、形態素解析のライブラリを入れる必要がある(Senとか)
・転置インデックスのため検索に漏れが出る。
例)「吾輩」で分かち書きされているものは「吾」で検索してもヒットしない
(検索語句を同ライブラリで分かち書きして検索すればある程度カバーできる)
・最新語句の分かち書きに対応できない。
・形態素解析の辞書をインストールする必要がある。
Lucene
上記のGINインデックスで作成したテーブルのレコードをLuceneに登録した。
インデックス約100万件程度
速度は10ms程度。
N-Gramのインデックスを作成した。
作り方は上のソースコードにある。
基本的には、IndexWriterを作成して、Documentクラスをつくって書き込む。
検索は、逆にIndexReaderを作成してSearcherを作って、Queryを作って検索する。
◇ メリット
・検索結果が望むものになりやすい。
・インデックス作成が高速。
・数億のインデックス作成が可能(Wikipediaでの実績)
・辞書を必要としない
◇ デメリット
・複数APサーバで運用している場合導入が煩雑
- インデックスは複数サーバから参照されなければいけないが、物理的なファイルなので、ファイルの置き場所を考慮しなければいけない。(Solr【Luceneの全文検索サーバ】?を導入してリモートでインデックスの参照、更新を行うことで対処。Hadoop導入)
・検索に引っかかりすぎることもある。
・Lucene独自のクエリーを使用する(学習コスト的に)
