PostgreSQL Ludiaインストールメモ
PostgreSQLの 全文検索、Ludiaインストールメモ。
PostgreSQL8.3.3以前のDBで運用しているLudiaのインストールと注意点に関するメモ。
参考サイト
http://sourceforge.jp/projects/ludia/
http://ludia.sourceforge.jp/cgi-bin/moin.cgi/
対応環境
・PostgreSQL : 8.1.10, 8.2系(8.3.3でも動作は確認。それ以降ではパッチをあてる必要があるため、素直にtextsearch_sennaを使うことをお勧めします)
・MeCab : ludia-withdeps-1.5.1.tar.gzの場合、同梱されています
・Senna : ludia-withdeps-1.5.1.tar.gzの場合、同梱されています
インストール手順
・PostgreSQLはインストール済みだとします。
・PostgreSQLのコンパイルディレクトリは「/usr/local/src/postgresql-8.3.3」だとします。
・PostgreSQLのインストールディレクトリは「/usr/local/pgsql」だとします。
・モジュールのバージョンは適宜よみかえてください。
Ludiaのダウンロードと解凍
PGXSを使いたくないので、contribの下で作業します。
cd /usr/local/src wget http://sourceforge.jp/projects/ludia/downloads/32462/ludia-withdeps-1.5.1.tar.gz tar zxf ludia-withdeps-1.5.1.tar.gz -C /usr/local/src/postgresql-8.3.3/contrib/
Mecabインストール
形態素解析で使用するMecabをインストールします。
ここでは、EUC-JPを使用します。
cd /usr/local/src/postgresql-8.3.3/contrib/ludia-1.5.1/deps tar zxf mecab-0.97.tar.gz cd mecab-0.97 ./configure --with-charset=euc-jp make su - cd /usr/local/src/postgresql-8.3.3/contrib/ludia-1.5.1/deps/mecab-0.97 make install exit
Mecab辞書をインストール
cd /usr/local/src/postgresql-8.3.3/contrib/ludia-1.5.1/deps/ tar zxf mecab-ipadic-2.7.0-20070801.tar.gz cd mecab-ipadic-2.7.0-20070801 ./configure --with-charset=euc-jp make su - cd /usr/local/src/postgresql-8.3.3/contrib/ludia-1.5.1/deps/mecab-ipadic-2.7.0-20070801 make install exit
Sennaインストール
Ngram方式の全文検索エンジン、Sennaをインストールします。
cd /usr/local/src/postgresql-8.3.3/contrib/ludia-1.5.1/deps tar zxf senna-1.1.3.tar.gz cd senna-1.1.3 ./configure make su - cd /usr/local/src/postgresql-8.3.3/contrib/ludia-1.5.1/senna-1.1.3 make install exit
Ludiaインストール
本体をインストールします。
cd /usr/local/src/postgresql-8.3.3/contrib/ludia-1.5.1/ ./configure make su - cd /usr/local/src/ludia-1.5.1 make install exit
Ludia設定
・インデックスアクセスメソッドの登録
psql -f /usr/local/pgsql/share/pgsenna2.sql DB名
・PostgreSQLの設定ファイルpostgresql.confに全文検索用の設定を追加
postgresql.conf
#------------------------------------------------------------------------------ # CUSTOMIZED OPTIONS #------------------------------------------------------------------------------ # list of custom variable class names custom_variable_classes = 'ludia' # 検索ヒット数の上限設定 ludia.max_n_sort_result = 10000 # ON : シーケンシャルスキャンを実行できる # OFF : シーケンシャルスキャンが実行された場合にエラー ludia.enable_seqscan = on # 0: 比較文字列を正規化せずに、シーケンシャルスキャンを行う # 1: 比較文字列を正規化した後、シーケンシャルスキャンを行う ludia.seqscan_flags = 1 # ludia.sen_index_flags = 19 (010011) # fulltextuでインデックスを作成したときに有効となるフラグ。 # 1bit: 英文字の大文字/小文字、全角文字/半角文字を正規化 # 2bit: N-gramインデックスで正規化を指定した際、英文字列もn文字の要素に分割する # 3bit: N-gramインデックスで正規化を指定した際、数字文字列もn文字の要素に分割する # 4bit: N-gramインデックスで正規化を指定した際、記号文字列もn文字の要素に分割する # 5bit: (形態素解析ではなく)n-gramを用いる # 6bit: (形態素解析ではなく)空白区切りで単語を区切る ludia.sen_index_flags = 19 # インデックスの同時オープン数の上限 ludia.max_n_index_cache = 16 # インデックスの初期サイズ ludia.initial_n_segments = 512
su - # 設定反映 /etc/init.d/postgres reload exit
使い方
・インデックスアクセスメソッドの種類
fulltext : 正規化 + 形態素解析 (SEN_INDEX_NORMALIZE)
fulltextb : 正規化 + 2-gram (SEN_INDEX_NORMALIZE|SEN_INDEX_NGRAM)
fulltextu : ユーザ定義
fulltexta : 配列型インデックス
・インデックスの作成
こんな感じ
# fulltextで作成 CREATE INDEX index1 ON table1 USING fulltext(col1); # マルチカラムインデックスをサポート CREATE INDEX index2 ON table1 USING fulltext(col1 text, col2 text); # 配列型インデックスをサポート CREATE INDEX index3 ON table1 USING fulltexta ((ARRAY[col1, col2, col3]));
・全文検索インデックスを使用した検索
8.3以降では、@@は予約語のため、%%で検索を行ってください。
「*D+」、「*W」などは、Sennaのクエリの書式に準拠します。
# hogeで SELECT * FROM table1 WHERE col1 @@ 'hoge'; # ヒットスコアを表示する。ctidはそのテーブル内のタプルのタプルIDです。 SELECT col1, pgs2getscore(table1.ctid, 'index1') FROM table1 WHERE col1 @@ 'hoge'; # AND検索 SELECT * FROM table1 WHERE col1 @@ '*D+ hoge fuga'; # OR検索。配列型インデックスを利用するとOR検索を高速に行うことができます。 SELECT * FROM test WHERE ARRAY[col1, col2, col3] @@ 'piyo'; # 重み付け検索 SELECT *, pgs2getscore(ctid) AS score FROM test WHERE array[col1, col2, col3] @@ '*W1:10,2:5,3:1 hello' ORDER BY score DESC;
・インデックスの削除
インデックスを削除する場合、不要なファイルが残ってしまうため以下のように削除してください。
DROP INDEX 全文検索インデックス名; CHECKPOINT; SELECT pgs2destroy();
・設定内容の表示
SELECT * FROM pgs2getoption();
・インデックスの情報を取得
SELECT * FROM pgs2indexinfo();
注意点
・Ludiaがインデックス対象とできるのはtext型のみ
・vacuum
vacuumを行うと、無効になったタプルに対するインデックス情報が残ってしまうため、インデックスの再作成が必要です。
vacuumdb -avz psql -q ${DB_NAME} <<_EOD_ DROP INDEX インデックス名; CHECKPOINT; SELECT pgs2destroy(); CREATE INDEX index1 ON table1 USING fulltext(col1); _EOD_