Help us understand the problem. What is going on with this article?

Groongaで一時カラム・動的カラムを使って計算結果でソートや集計する方法

More than 3 years have passed since last update.

はじめに

全文検索エンジンのGroongaは全文検索エンジンの機能だけでなく、カラム指向型のデータストアとしての機能も備えています。

今年も様々な機能が追加・改良されましたが、割とドキュメントが追い付いていない感じで、リリースノートやコマンドのテストケースを読むと追加された新機能の存在や使い方を知ることができます。

ここでは、一時カラム(動的カラム)の機能について紹介します。

一時カラムについて

Groongaでは一時カラム(動的カラム)が作成できるようになりました。今までoutput_columnsで関数をかけながら出力をすることができましたが、関数をかけた後の値を使って、ソートやフィルターなどをかけることはできませんでした。一時カラムを使うと、計算結果後の値を利用して、ソートやフィルターなどをかけることができます。

以下は一時カラムを使う例です。pricediscount_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_columnssort_keysdrilldownsなどで計算結果後の一時カラムを指定ができるようになります。SQLでいうASで別名をつけて指定するようなものです。ASと違い型情報も与えなければいけません。

columns[label_name].type

column_createtypeと同様にカラムの型を指定します。例えば、UInt32ShortTextまたはテーブル名などです。

columns[label_name].flags

column_createflagsと同様にカラムのフラグを指定します。例えば、COLUMN_SCALARCOLUMN_VECTORなどです。

columns[label_name].value

スクリプト構文の式を書きます。たとえば、(title + "a")とかくとtitleカラムに文字列"a"が追加されますし、snippet_html(title)など関数を書くこともできます。

columns[label_name].stage

stageとは一時カラムを作成するタイミングのことで、これにより関数の評価対象と使える処理の対象が変わってきます。

initial

queryfilterの絞り込み前、最初の段階の検索対象テーブルを元にして一時カラムを作成します。queryfilterdrilldownsort_keys, output_columnsのすべてで使用することができます。valueは検索対象テーブルの全件のレコードに対して評価されます。

filtered

queryfilterが適用された後の検索結果を元にして一時カラムを作成します。drilldownsort_keys, output_columnsで使用することができます。valueは検索結果の絞り込み件数のレコードに対して評価されます。

output

sort_keyslimitoffsetが適用された後のソート結果、出力数制限の結果を元にして一時カラムを作成します。output_columnsで使用することができます。valueは出力するlimit件数のレコードに対して評価されます。

おわりに

一時カラムは、用途に応じて適切なstageを選択する必要があります。initialfilteredでは、多くのレコードがシーケンシャルに処理されます。

snippethighlightなどの実際に出力するものだけに適用すればいいものは、outputステージを選択するべきです。

drilldownsort_keysに使いたい場合は、filteredを使用するべきです。

検索結果でも100万件を超えるような場合、時間がかかりすぎるので事前に計算したカラムを用意することをお勧めします。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした