はじめに
全文検索エンジンのGroongaは全文検索エンジンの機能だけでなく、カラム指向型のデータストアとしての機能も備えています。
今年も様々な機能が追加・改良されましたが、割とドキュメントが追い付いていない感じで、リリースノートやコマンドのテストケースを読むと追加された新機能の存在や使い方を知ることができます。
ここでは、一時カラム(動的カラム)の機能について紹介します。
一時カラムについて
Groongaでは一時カラム(動的カラム)が作成できるようになりました。今までoutput_columnsで関数をかけながら出力をすることができましたが、関数をかけた後の値を使って、ソートやフィルターなどをかけることはできませんでした。一時カラムを使うと、計算結果後の値を利用して、ソートやフィルターなどをかけることができます。
以下は一時カラムを使う例です。priceにdiscount_rateを反映させたdiscount_priceという一時カラムを作成して、その一時カラムでソートしています。
table_create books TABLE_NO_KEY
[[0,0.0,0.0],true]
column_create books title COLUMN_SCALAR ShortText
[[0,0.0,0.0],true]
column_create books price COLUMN_SCALAR UInt32
[[0,0.0,0.0],true]
column_create books discount_rate COLUMN_SCALAR Float
[[0,0.0,0.0],true]
load --table books
[
{"title": "自動車教習本", "price": 1000, "discount_rate": 0.0},
{"title": "働く車", "price": 500, "discount_rate": 0.1},
{"title": "自転車の乗り方", "price": 1200, "discount_rate": 0.2}
]
[[0,0.0,0.0],3]
select books \
--columns[discount_price].stage filtered \
--columns[discount_price].type Float \
--columns[discount_price].flags COLUMN_SCALAR \
--columns[discount_price].value 'price - (price * discount_rate)' \
--sort_keys discount_price \
--output_columns title,discount_price,price
[
[
0,
0.0,
0.0
],
[
[
[
3
],
[
[
"title",
"ShortText"
],
[
"discount_price",
"Float"
],
[
"price",
"UInt32"
]
],
[
"働く車",
450.0,
500
],
[
"自転車の乗り方",
960.0,
1200
],
[
"自動車教習本",
1000.0,
1000
]
]
]
]
構文がややこしいのですが、columns[label_name].~とすることで、新たにオンメモリ上の一時カラムを計算結果テーブルに紐づけることができ、output_columnsやsort_keys、drilldownsなどで計算結果後の一時カラムを指定ができるようになります。SQLでいうASで別名をつけて指定するようなものです。ASと違い型情報も与えなければいけません。
columns[label_name].type
column_createのtypeと同様にカラムの型を指定します。例えば、UInt32やShortTextまたはテーブル名などです。
columns[label_name].flags
column_createのflagsと同様にカラムのフラグを指定します。例えば、COLUMN_SCALARやCOLUMN_VECTORなどです。
columns[label_name].value
スクリプト構文の式を書きます。たとえば、(title + "a")とかくとtitleカラムに文字列"a"が追加されますし、snippet_html(title)など関数を書くこともできます。
columns[label_name].stage
stageとは一時カラムを作成するタイミングのことで、これにより関数の評価対象と使える処理の対象が変わってきます。
initial
queryとfilterの絞り込み前、最初の段階の検索対象テーブルを元にして一時カラムを作成します。query、filter、drilldown、sort_keys, output_columnsのすべてで使用することができます。valueは検索対象テーブルの全件のレコードに対して評価されます。
filtered
queryとfilterが適用された後の検索結果を元にして一時カラムを作成します。drilldown、sort_keys, output_columnsで使用することができます。valueは検索結果の絞り込み件数のレコードに対して評価されます。
output
sort_keys、limit、offsetが適用された後のソート結果、出力数制限の結果を元にして一時カラムを作成します。output_columnsで使用することができます。valueは出力するlimit件数のレコードに対して評価されます。
おわりに
一時カラムは、用途に応じて適切なstageを選択する必要があります。initialやfilteredでは、多くのレコードがシーケンシャルに処理されます。
snippetやhighlightなどの実際に出力するものだけに適用すればいいものは、outputステージを選択するべきです。
drilldownやsort_keysに使いたい場合は、filteredを使用するべきです。
検索結果でも100万件を超えるような場合、時間がかかりすぎるので事前に計算したカラムを用意することをお勧めします。