groonga、textsearch_groonga使い方めも
groonga、textsearch_groongaを使ったときのメモなど。
groongaはv1.1.0、textsearch_groongaはversion 0.1で確認。
参考サイト
groonga
textsearch_groonga
所感
versionもまだ0.1ですし、いろいろと思い違いをしているところなどあるとおもいますが、textsearch_groongaをtextsearch_sennaと比べると、結構いい感じに思います。
メリット
自前のストレージを持っている
マルチカラムインデックスが使える
更新時の不整合解消、非同期処理性能向上(groongaサーバモードのときかも?)
スコアリング対応
groongaをHTTPモードで起動してインデックスサーバを併用できる
デメリット
インデックス削除でごみが残る
ストリーミングレプリケーション非対応
like検索非対応
その他
DBはUTF-8で構築するのがよい
今のところ、%%ではなくgroonga.query()を使うこと
マルチカラムインデックスがいい感じ(explain結果)
HTTPで通信できるgroongaサーバがおもしろい。管理画面もある
vacuum、vacuum full対策不明(要調査)
groongaの設定をどこでするのか不明(要調査)
textsearch_groongaで検索
「一般的な比較演算子に加え、全文検索用の %% 演算子と、groonga クエリを直接記述できる @@ 演算子をサポートしています。
ただし、現在のバージョンでは textsearch_senna とは異なり、LIKE 演算子はサポートしていません。また、CREATE INDEX の際に WITH 句で指定できるインデックス・オプションはありません。 」
とのことです。
インデックス作成
using groongaを指定してインデックスを作成します。
また、マルチカラムインデックスを指定できます。
# インデックス create index test_gidx_01 on test using groonga (name); # 部分インデックス create index test_gidx_02 on test using groonga (name) where gender = 1; # マルチカラムインデックス create index test_gidx_03 on test using groonga (name, introduction);
%% 演算子
OPERATOR %% (document text, query text)
# %%で検索 =# select uid, name, groonga.score(tableoid, ctid) from test where name %% 'test'; uid | name | score --------+--------------+------- 268278 | test001 | 2 270929 | test002 | 1 # %%でのAND,OR検索は今のところ非対応の模様 =# select uid, name, groonga.score(tableoid, ctid) from test where name %% 'test 01'; RROR: unexpected result: NULL CONTEXT: query: select --table t232868095 --sortby _key --output_columns _key,_score --limit -1 --query "(name:@test\ 01)"
groonga.query()で検索
@@ の左辺の列名は、使用する groonga インデックスの列の任意のいずれか1つで構いません。検索条件として使う列は、groonga.query() で与えます。
groonga.query('検索ワード', '検索カラム')
# 検索 =# select uid, name, groonga.score(tableoid, ctid) from test where name @@ groonga.query('test', 'name') uid | name | score --------+--------------+------- 268278 | test001 | 2 270929 | test002 | 1 # 複数のカラムを検索 =# select uid, name, groonga.score(tableoid, ctid) from test where introduction @@ groonga.query('test', 'name||introduction'); uid | name | score --------+--------------+------- 268278 | test001 | 2 270929 | test002 | 1 207821 | data003 | 1 # 複数のカラムを重み付け検索 =# select uid, name, groonga.score(tableoid, ctid) from test where introduction @@ groonga.query('test', 'name*10||introduction'); uid | name | score --------+--------------+------- 268278 | test001 | 20 270929 | test002 | 10 207821 | data003 | 1 # AND検索 =# select uid, name, groonga.score(tableoid, ctid) from test where name @@ groonga.query('test 01', 'name'); # OR検索 =# select uid, name, groonga.score(tableoid, ctid) from test where name @@ groonga.query('test OR data', 'name');
%%とgroonga.query()の比較
expainのクエリプランを比較してみます。
・単純検索
### %% =# explain select name, groonga.score(tableoid, ctid) from test where name %% 'test'; QUERY PLAN ------------------------------------------------------------------------------------------- Index Scan using test_gidx_03 on test (cost=0.25..164.10 rows=80 width=18) Index Cond: ((name)::text %% 'test'::text) ### groonga.query() =# explain select name, groonga.score(tableoid, ctid) from test where name @@ groonga.query('test', 'name'); QUERY PLAN ---------------------------------------------------------------------------------------- Bitmap Heap Scan on test (cost=311.34..5825.59 rows=39883 width=22) Recheck Cond: (name @@ '--query "test" --match_columns "name"'::groonga.query) -> Bitmap Index Scan on test_gidx_03 (cost=0.00..301.37 rows=39883 width=0) Index Cond: (name @@ '--query "test" --match_columns "name"'::groonga.query)
・AND検索
### %% =# explain select name, groonga.score(tableoid, ctid) from test where name %% 'test' and name %% 'うら'; QUERY PLAN ---------------------------------------------------------------------------------------- Index Scan using test_gidx_03 on test (cost=0.49..4.77 rows=1 width=22) Index Cond: (((name)::text %% 'test'::text) AND ((name)::text %% 'うら'::text)) ### groonga.query() =# explain select name, groonga.score(tableoid, ctid) from test where name @@ groonga.query('test うら' , 'name'); QUERY PLAN ------------------------------------------------------------------------------------------- Bitmap Heap Scan on test (cost=311.34..5825.59 rows=39883 width=22) Recheck Cond: (name @@ '--query "test\\ うら" --match_columns "name"'::groonga.query) -> Bitmap Index Scan on test_gidx_03 (cost=0.00..301.37 rows=39883 width=0) Index Cond: (name @@ '--query "test\\ うら" --match_columns "name"'::groonga.query)
・OR検索
### %% =# explain select name, groonga.score(tableoid, ctid) from test where name %% 'test' or name %% 'うら'; QUERY PLAN ----------------------------------------------------------------------------------------- Bitmap Heap Scan on test (cost=6.27..375.95 rows=159 width=22) Recheck Cond: (((name)::text %% 'test'::text) OR ((name)::text %% 'うら'::text)) -> BitmapOr (cost=6.27..6.27 rows=160 width=0) -> Bitmap Index Scan on test_gidx_03 (cost=0.00..3.10 rows=80 width=0) Index Cond: ((name)::text %% 'test'::text) -> Bitmap Index Scan on test_gidx_03 (cost=0.00..3.10 rows=80 width=0) Index Cond: ((name)::text %% 'うら'::text) ### groonga.query() =# explain select name, groonga.score(tableoid, ctid) from test where name @@ groonga.query('test OR うら', 'name'); QUERY PLAN ------------------------------------------------------------------------------------------------ Bitmap Heap Scan on test (cost=311.34..5825.59 rows=39883 width=22) Recheck Cond: (name @@ '--query "test\\ OR\\ うら" --match_columns "name"'::groonga.query) -> Bitmap Index Scan on test_gidx_03 (cost=0.00..301.37 rows=39883 width=0) Index Cond: (name @@ '--query "test\\ OR\\ うら" --match_columns "name"'::groonga.query)
・マルチカラム検索
### %% =# explain select name, groonga.score(tableoid, ctid) from test where name %% 'test' or introduction %% 'test'; QUERY PLAN ----------------------------------------------------------------------------------------- Bitmap Heap Scan on test (cost=6.27..375.95 rows=159 width=22) Recheck Cond: (((name)::text %% 'test'::text) OR (introduction %% 'test'::text)) -> BitmapOr (cost=6.27..6.27 rows=160 width=0) -> Bitmap Index Scan on test_gidx_03 (cost=0.00..3.10 rows=80 width=0) Index Cond: ((name)::text %% 'test'::text) -> Bitmap Index Scan on test_gidx_03 (cost=0.00..3.10 rows=80 width=0) Index Cond: (introduction %% 'test'::text) ### groonga.query() =# explain select name, groonga.score(tableoid, ctid) from test where name @@ groonga.query('test', ' name||introduction'); QUERY PLAN ---------------------------------------------------------------------------------------------------- Bitmap Heap Scan on test (cost=311.34..5825.59 rows=39883 width=22) Recheck Cond: (name @@ '--query "test" --match_columns "name||introduction"'::groonga.query) -> Bitmap Index Scan on test_gidx_03 (cost=0.00..301.37 rows=39883 width=0) Index Cond: (name @@ '--query "test" --match_columns "name||introduction"'::groonga.query)
groonga(コマンドモード)で検索
PostgreSQLの全文検索インデックスで作成したストレージファイルにgroonga(コマンドモード)でアクセスすることができます。
PostgreSQLでgroonga使用時のストレージファイルは、{PostgreSQLデータディレクトリ}/base/データベースのOID/grnとなっています。パスなどの設定が{PostgreSQLデータディレクトリ}を基準に設定してあるため、{PostgreSQLデータディレクトリ}でgroongaコマンドを実行する必要があります。
groongaオープン
cd /usr/local/pgsql/data groonga base/16414/grn
groongaコマンドモード
# --queryで検索カラム指定 > select --table t232867959 --query "name:@\"test\"" [[0,1301479281.22904,0.000446],[[[2],[["_key","Int64"],["_score","Int32"],["name","ShortText"]],[28049425,1,"testおうか"],[254607369,1,"testうらばん"]]]] # --match_columnsで検索カラム指定 > select --table t232867959 --match_columns name --query "test" [[0,1301479323.02256,0.000414],[[[2],[["_key","Int64"],["_score","Int32"],["name","ShortText"]],[28049425,1,"testおうか"],[254607369,1,"testうらばん"]]]] # --match_columns複数指定 > select --table t232868095 --match_columns "name||introduction" --query "testう" [[0,1301479702.79753,0.002362],[[[1],[["_key","Int64"],["_score","Int32"],["name","ShortText"]],[254607369,2,"testうらばん"]]]] # 絞込み検索 > select --table t232868095 --match_columns "name" --query "test\ うら" [[0,1301479769.08768,0.002223],[[[1],[["_key","Int64"],["_score","Int32"],["name","ShortText"]],[254607369,2,"testうらばん"]]]] # OR検索 > select --table t232868095 --match_columns "name" --query "test\ OR\ うら" [[0,1301479836.42993,0.002367],[[[12],[["_key","Int64"],["_score","Int32"],["name","ShortText"]],[28049425,1,"testおうか"],[43515908,1,"うらわざ"],[105775113,1,"うらら(p_q)"],[111214612,1,"うらら"],[114360329,1,"ゆうら"],[175439873,1,"うらのり"],[189333515,1,"たまうら"],[196018181,1,"うらら"],[225050635,1,"うららん"],[232980494,1,"ゆうら☆"],[254607369,2,"testうらばん"],[271187970,1,"つうら"]]]]
groonga(HTTPプロトコルモード)で検索
参考サイト
http://groonga.org/docs/tutorial/tutorial02.html
「MySQLプロトコルでデータの更新を行い、HTTPでデータの参照を行うことができます」との記述があったので、PostgreSQLでも試してみました。
・PostgreSQLの全文検索インデックスで作成したストレージファイルにgroonga(HTTPプロトコルモード)でアクセスする。
サーバ起動
・起動
書式
groonga [-p ポート番号] -d --protocol http DBパス名
groonga(コマンドモード)のときと同様、{PostgreSQLデータディレクトリ}で起動する必要があります。
cd /usr/local/pgsql/data groonga -p 8080 -d --protocol http base/16414/grn
検索
http://[IPまたはホスト名]:[ポート番号]/d/status
http://172.30.0.160:8080/d/status
http://[IPまたはホスト名]:[ポート番号]/d/select?table=[テーブル]&query=[クエリ]
テーブルIDは管理画面から確認してください。
こんな感じで
# http://92.168.0.1:8080/d/select?table=t232867959&output_columns=_key,_score,name&limit=-1&query=name:@test # 出力 [[0,1301480525.33205,0.000413],[[[2],[["_key","Int64"],["_score","Int32"],["name","ShortText"]],[28049425,1,"testおうか"],[254607369,1,"testうらばん"]]]]