PostgreSQLの全文検索でLudia, textsearch_sennaを使っていたのですが、9.2ではどちらも使えないので、代替となりそうなものを探した結果、pg_trgm, pg_bigm, textsearch_jaの三つが使えそうでした。
ただpg_trgmは日本語を使うにはソースからのコンパイルが必要で、しかも二文字以下は使えないのでパスしました。
textsearch_jaはtsvectorの拡張のようです。
とりあえずtextsearch_jaをインストールしてみます。
gcc-c++とかが必要らしいので事前にインストールしておきました。
まずはmecab。
http://taku910.github.io/mecab/#download
mecab本体とipa辞書をダウンロード。
PostgreSQLの文字コードはデフォルトUTF-8なのでconfigureオプションには、
--with-charset=utf8
をどちらも追加しないと駄目でした。
その後、/etc/ld.so.conf.d/mecab.confを作成して以下一行を追加。
/usr/local/lib
この後ldconfigを実施します。
次にtextsearch_ja本体
http://textsearch-ja.projects.pgfoundry.org/textsearch_ja.html
tar xzf textsearch_ja-9.0.0.tar.gz
cd textsearch_ja-9.0.0/
make USE_PGXS=1
make USE_PGXS=1 install
/usr/share/pgsql/contrib/textsearch_ja.sql はそのまま実行すると駄目で、’C’を小文字に直すか、クォートを外す必要が有りました。
psql [database] -f /usr/share/pgsql/contrib/textsearch_ja.sql
psql [database]
CREATE INDEX test_tb_content ON test_tb USING gin(to_tsvector('japanese', content));
実行結果
EXPLAIN SELECT * FROM test_tb WHERE to_tsvector('japanese', content) @@ to_tsquery('japanese', '猫');
QUERY PLAN
----------------------------------------------------------------------------------------
Bitmap Heap Scan on test_tb (cost=19.65..1470.66 rows=471 width=529)
Recheck Cond: (to_tsvector('japanese'::regconfig, content) @@ '''猫'''::tsquery)
-> Bitmap Index Scan on test_tb_content (cost=0.00..19.53 rows=471 width=0)
Index Cond: (to_tsvector('japanese'::regconfig, content) @@ '''猫'''::tsquery)
(4 行)
pg_bigmはpg_trgmの拡張のようです。
http://pgbigm.osdn.jp/pg_bigm-1-2.html#install
PostgreSQLについてはrpm版を使うので省略。
またインストールにはpostgresql-develが必要なので事前にインストールしておきます。
CentOS6用のrpmが有りましたが、CentOS7のデフォルトのpostgresqlでは使えなかったのでダウンロードしてmakeします。
pg_configはデフォルトパスが通っているので、オプションは入れずに実行可能です。
tar xzf pg_bigm-1.2-20161011.tar.gz
cd pg_bigm-1.2-20161011/
make USE_PGXS=1
make USE_PGXS=1 install
スーパーユーザーでデータベースごとにextensionを追加します。
su - postgres
psql [database]
CREATE EXTENSION pg_bigm;
インデックスを追加して実行してみます。
CREATE INDEX test_tb_content_bigm ON test_tb USING gin (content gin_bigm_ops);
EXPLAIN SELECT * FROM test_tb WHERE content LIKE '%猫%';
QUERY PLAN
---------------------------------------------------------------------------------------
Bitmap Heap Scan on test_tb (cost=40.06..71.29 rows=8 width=529)
Recheck Cond: (content ~~ '%猫%'::text)
-> Bitmap Index Scan on test_tb_content_bigm (cost=0.00..40.06 rows=8 width=0)
Index Cond: (content ~~ '%猫%'::text)
(4 行)
単純な結果としては、pg_bigmの方が有利なのかなといった感じでした。