前回はpg_bigmをつかってPostgreSQLで全文検索を行う方法を試しました。数年前から登場し、PostgreSQLの日本語全文検索ではpg_bigmと同じくらい耳にするPGroongaを試してみます。
PGroonga?
以下はドキュメントからの抜粋です。
PGroongaはPostgreSQLの拡張機能です。PGroongaはGroongaを使った新しいインデックスアクセスメソッドを提供します。 Groongaは組み込み可能な超高速全文検索エンジンです。GroongaはMySQLにも組み込めます。MroongaはGroongaベースのストレージエンジンです。Groongaはスタンドアローンの検索エンジンとしても使えます。 PostgreSQLはアルファベットと数値だけを使った言語の全文検索だけをサポートしています。これは、日本語や中国語などはサポートしていないということです。PGroongaをPostgreSQLにインストールすると全言語対応の超高速全文検索機能を使えるようになります! さらに、PGroongaはJSON内のすべてのテキスト値に対する全文検索もサポートしています。これは他にはない機能です。組み込みのPostgreSQLの機能でもJsQueryでもサポートしていません。
GroongaをPostgreSQLから利用できるようにする拡張のようです。
対象環境
今回は以下の環境で実施しました。
- Ubuntu 16.04
- PostgreSQL 9.6.5
- PGroonga 2.0.1
Groonga
Groongaを使うので当然先にインストールしなければいけません。各プラットフォーム向けにパッケージがあるみたいですが、ソースからコンパイルしてみます。手順はこれです。
依存パッケージの準備
先に必要なパッケージを入れておきます。
sudo apt-get install -y -V wget tar build-essential pkg-config zlib1g-dev libmsgpack-dev libzmq3-dev libevent-dev libmecab-dev liblz4-dev libzstd-dev
ソースの準備
Groongaのソースを準備します。
denzow@denzow-ubuntu:~/work/groonga$ mkdir -p ~/work/groonga/ denzow@denzow-ubuntu:~/work/groonga$ cd ~/work/groonga/ denzow@denzow-ubuntu:~/work/groonga$ wget https://packages.groonga.org/source/groonga/groonga-7.0.6.tar.gz --2017-09-10 12:57:20-- https://packages.groonga.org/source/groonga/groonga-7.0.6.tar.gz packages.groonga.org (packages.groonga.org) をDNSに問いあわせています... 133.18.25.129 packages.groonga.org (packages.groonga.org)|133.18.25.129|:443 に接続しています... 接続しました。 HTTP による接続要求を送信しました、応答を待っています... 200 OK 長さ: 14558308 (14M) [application/x-gzip] `groonga-7.0.6.tar.gz' に保存中 groonga-7.0.6.tar.gz 100%[============================================================================================================================================================>] 13.88M 3.29MB/s in 4.3s 2017-09-10 12:57:25 (3.21 MB/s) - `groonga-7.0.6.tar.gz' へ保存完了 [14558308/14558308] denzow@denzow-ubuntu:~/work/groonga$ tar xzf groonga-7.0.6.tar.gz denzow@denzow-ubuntu:~/work/groonga$ cd groonga-7.0.6 denzow@denzow-ubuntu:~/work/groonga/groonga-7.0.6$
ビルド
ビルドしていきます。インストール先だけ変更するので--prefix
を指定しておきます。
denzow@denzow-ubuntu:~/work/groonga/groonga-7.0.6$ mkdir -p ~/groongaHome/groonga-7.0.6 denzow@denzow-ubuntu:~/work/groonga/groonga-7.0.6$ ./configure --prefix=$HOME/groongaHome/groonga-7.0.6 : Tools: Sphinx: lemon: none Ruby: Cutter: For packages: rsync path: packages@packages.groonga.org:public Launchpad PGP key: GPG UID: 45499429 Now type 'make' to build groonga 7.0.6!
できたようなのでmake && make install
します。
denzow@denzow-ubuntu:~/work/groonga/groonga-7.0.6$ make -j4 denzow@denzow-ubuntu:~/work/groonga/groonga-7.0.6$ make install
インストールできてるか試してみます。
denzow@denzow-ubuntu:~/work/groonga/groonga-7.0.6$ /home/denzow/groongaHome/groonga-7.0.6/bin/groonga --version Groonga 7.0.6 [linux-gnu,x86_64,utf8,match-escalation-threshold=0,nfkc,mecab,msgpack,onigmo,zlib,lz4,zstd,epoll] configure options: < '--prefix=/home/denzow/groongaHome/groonga-7.0.6'>
入ったようです。恐らくPATHやLD_LIBRARY_PATHは通さないといけないはずですので、.bashrc
に追記しておきます。
denzow@denzow-ubuntu:~/work/groonga/groonga-7.0.6$ echo 'export PATH=$PATH:/home/denzow/groongaHome/groonga-7.0.6/bin/' >> ~/.bashrc denzow@denzow-ubuntu:~/work/groonga/groonga-7.0.6$ echo 'export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/denzow/groongaHome/groonga-7.0.6/lib/' >> ~/.bashrc denzow@denzow-ubuntu:~/work/groonga/groonga-7.0.6$ . ~/.bashrc
PGroonga
ソースからビルドするのが好きなので、ドキュメントを参考にしながら試していきます。
依存パッケージの準備
WALを生成させるにはlibmsgpack-devが必要らしいので先に入れておきます。Groongaをいれているのであれば入ってそうですが。
denzow@denzow-ubuntu:~/work/pgroonga/pgroonga-2.0.1$ sudo apt-get install libmsgpack-dev
ソースの準備
ソースを持ってきて準備します。
denzow@denzow-ubuntu:~/work/pgroonga$ mkdir -p ~/work/pgroonga/ denzow@denzow-ubuntu:~/work/pgroonga$ cd ~/work/pgroonga/ denzow@denzow-ubuntu:~/work/pgroonga$ wget https://packages.groonga.org/source/pgroonga/pgroonga-2.0.1.tar.gz --2017-09-10 12:50:24-- https://packages.groonga.org/source/pgroonga/pgroonga-2.0.1.tar.gz packages.groonga.org (packages.groonga.org) をDNSに問いあわせています... 133.18.25.129 packages.groonga.org (packages.groonga.org)|133.18.25.129|:443 に接続しています... 接続しました。 HTTP による接続要求を送信しました、応答を待っています... 200 OK 長さ: 264156 (258K) [application/x-gzip] `pgroonga-2.0.1.tar.gz' に保存中 pgroonga-2.0.1.tar.gz 100%[============================================================================================================================================================>] 257.96K --.-KB/s in 0.1s 2017-09-10 12:50:24 (2.58 MB/s) - `pgroonga-2.0.1.tar.gz' へ保存完了 [264156/264156] denzow@denzow-ubuntu:~/work/pgroonga$ tar xf pgroonga-2.0.1.tar.gz denzow@denzow-ubuntu:~/work/pgroonga$ cd pgroonga-2.0.1 denzow@denzow-ubuntu:~/work/pgroonga/pgroonga-2.0.1$
ビルド
HAVE_MSGPACK=1
つきでビルドしてみます。
denzow@denzow-ubuntu:~/work/pgroonga/pgroonga-2.0.1$ make HAVE_MSGPACK=1 make -f pgroonga.mk all make[1]: ディレクトリ '/home/denzow/work/pgroonga/pgroonga-2.0.1' に入ります Package msgpack was not found in the pkg-config search path. Perhaps you should add the directory containing `msgpack.pc' to the PKG_CONFIG_PATH environment variable No package 'msgpack' found Package groonga was not found in the pkg-config search path. Perhaps you should add the directory containing `groonga.pc' to the PKG_CONFIG_PATH environment variable No package 'groonga' found gcc -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -O2 -Ivendor/xxHash -DPGRN_HAVE_MSGPACK -DPGRN_VERSION="\"2.0.1\"" -fPIC -I. -I./ -I/home/denzow/posgreHome/pg965/include/postgresql/server -I/home/denzow/posgreHome/pg965/include/postgresql/internal -D_GNU_SOURCE -I/usr/include/libxml2 -c -o src/pgroonga.o src/pgroonga.c In file included from src/pgroonga.c:5:0: src/pgrn-command-escape-value.h:3:21: fatal error: groonga.h: そのようなファイルやディレクトリはありません compilation terminated. <ビルトイン>: ターゲット 'src/pgroonga.o' のレシピで失敗しました make[1]: *** [src/pgroonga.o] エラー 1 make[1]: ディレクトリ '/home/denzow/work/pgroonga/pgroonga-2.0.1' から出ます Makefile:2: ターゲット 'all' のレシピで失敗しました make: *** [all] エラー 2
おや。失敗しました。No package 'msgpack' found
やNo package 'groonga' found
が原因っぽいです。恐らくインストール先をいじっているからでしょう。マニュアルをよく見るとこの場合はPKG_CONFIG_PATH
環境変数を使えと書いてありました。msgpack.pcとgroonga.pcが配置されている場所を追加して実行します。
denzow@denzow-ubuntu:~/work/pgroonga/pgroonga-2.0.1$ echo 'export PKG_CONFIG_PATH=$HOME/groongaHome/groonga-7.0.6/lib/pkgconfig/:$HOME/work/pgroonga/pgroonga-2.0.1/data/travis/pkgconfig/' >> ~/.bashrc denzow@denzow-ubuntu:~/work/pgroonga/pgroonga-2.0.1$ . ~/.bashrc denzow@denzow-ubuntu:~/work/pgroonga/pgroonga-2.0.1$ make HAVE_MSGPACK=1 make -f pgroonga.mk all : make[1]: ディレクトリ '/home/denzow/work/pgroonga/pgroonga-2.0.1' から出ます denzow@denzow-ubuntu:~/work/pgroonga/pgroonga-2.0.1$ make install make -f pgroonga.mk install make[1]: ディレクトリ '/home/denzow/work/pgroonga/pgroonga-2.0.1' に入ります /bin/mkdir -p '/home/denzow/posgreHome/pg965/lib/postgresql' /bin/mkdir -p '/home/denzow/posgreHome/pg965/share/postgresql/extension' /bin/mkdir -p '/home/denzow/posgreHome/pg965/share/postgresql/extension' /usr/bin/install -c -m 755 pgroonga.so '/home/denzow/posgreHome/pg965/lib/postgresql/pgroonga.so' /usr/bin/install -c -m 644 .//pgroonga.control '/home/denzow/posgreHome/pg965/share/postgresql/extension/' /usr/bin/install -c -m 644 .//data/pgroonga--2.0.1.sql .//data/pgroonga--1.0.0--1.0.1.sql .//data/pgroonga--1.0.1--1.0.2.sql .//data/pgroonga--1.0.2--1.0.3.sql .//data/pgroonga--1.0.3--1.0.4.sql .//data/pgroonga--1.0.4--1.0.5.sql .//data/pgroonga--1.0.5--1.0.6.sql .//data/pgroonga--1.0.6--1.0.7.sql .//data/pgroonga--1.0.7--1.0.8.sql .//data/pgroonga--1.0.8--1.0.9.sql .//data/pgroonga--1.0.9--1.1.0.sql .//data/pgroonga--1.1.0--1.1.1.sql .//data/pgroonga--1.1.1--1.1.2.sql .//data/pgroonga--1.1.2--1.1.3.sql .//data/pgroonga--1.1.3--1.1.4.sql .//data/pgroonga--1.1.4--1.1.5.sql .//data/pgroonga--1.1.5--1.1.6.sql .//data/pgroonga--1.1.6--1.1.7.sql .//data/pgroonga--1.1.7--1.1.8.sql .//data/pgroonga--1.1.8--1.1.9.sql .//data/pgroonga--1.1.9--1.2.0.sql .//data/pgroonga--1.2.0--1.2.1.sql .//data/pgroonga--1.2.1--1.2.2.sql .//data/pgroonga--1.2.2--1.2.3.sql .//data/pgroonga--1.2.3--2.0.0.sql .//data/pgroonga--2.0.0--2.0.1.sql '/home/denzow/posgreHome/pg965/share/postgresql/extension/' make[1]: ディレクトリ '/home/denzow/work/pgroonga/pgroonga-2.0.1' から出ます make -f pgroonga-check.mk install make[1]: ディレクトリ '/home/denzow/work/pgroonga/pgroonga-2.0.1' に入ります /bin/mkdir -p '/home/denzow/posgreHome/pg965/lib/postgresql' /usr/bin/install -c -m 755 pgroonga_check.so '/home/denzow/posgreHome/pg965/lib/postgresql/pgroonga_check.so' make[1]: ディレクトリ '/home/denzow/work/pgroonga/pgroonga-2.0.1' から出ます
インストールできたようです。
DBへのロード
インストールをみていると、とりあえずテストDBを作ってそこにロードしているので従います。
denzow@denzow-ubuntu:~$ createdb pgroonga_test denzow@denzow-ubuntu:~$ psql pgroonga_test psql (9.6.5) Type "help" for help. pgroonga_test=# CREATE EXTENSION pgroonga; CREATE EXTENSION
サンプルの実行
早速、PGroongaを使ったINDEXを試してみます。手順はチュートリアルを参考にします。
pgroonga_test=# CREATE TABLE memos ( pgroonga_test(# id integer, pgroonga_test(# content text pgroonga_test(# ); CREATE TABLE pgroonga_test=# pgroonga_test=# CREATE INDEX pgroonga_content_index ON memos USING pgroonga (content); CREATE INDEX pgroonga_test=# INSERT INTO memos VALUES (1, 'PostgreSQLはリレーショナル・データベース管理システムです。'); INSERT 0 1 pgroonga_test=# INSERT INTO memos VALUES (2, 'Groongaは日本語対応の高速な全文検索エンジンです。'); INSERT 0 1 pgroonga_test=# INSERT INTO memos VALUES (3, 'PGroongaはインデックスとしてGroongaを使うためのPostgreSQLの拡張機能です。'); INSERT 0 1 pgroonga_test=# INSERT INTO memos VALUES (4, 'groongaコマンドがあります。'); INSERT 0 1 pgroonga_test=# pgroonga_test=# SET enable_seqscan = off; SET pgroonga_test=# pgroonga_test=# SELECT * FROM memos WHERE content &@ '全文検索'; id | content ----+--------------------------------------------------- 2 | Groongaは日本語対応の高速な全文検索エンジンです。 (1 row) pgroonga_test=# explain analyze SELECT * FROM memos WHERE content &@ '全文検索'; QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------- Bitmap Heap Scan on memos (cost=0.16..10.85 rows=635 width=36) (actual time=0.424..0.425 rows=1 loops=1) Recheck Cond: (content &@ '全文検索'::text) Heap Blocks: exact=1 -> Bitmap Index Scan on pgroonga_content_index (cost=0.00..0.00 rows=13 width=0) (actual time=0.413..0.413 rows=1 loops=1) Index Cond: (content &@ '全文検索'::text) Planning time: 0.137 ms Execution time: 0.641 ms (7 rows)
ちゃんとBitmap Index Scan on pgroonga_content_index
になっているので構築できているようです。