12月11日のGroonga読書会で学んだ内容をまとめます
今回は[4.7. match_columnsパラメータ]("4.7. match_columnsパラメータ" http://groonga.org/ja/docs/tutorial/match_columns.html)の章を輪読しました。
match_columsの話、というよりもインデックス周りの話が多かった気がします。
何故インデックスを貼るのか
全文検索を高速に行うためにインデックスを貼ります。
その他については他に詳しく解説されている方がいるので特に言及はしません。
Groongaにおけるインデックスカラムの引数について
例えば、以下のようなDDLがあった場合、
table_create --name Index --flags TABLE_PAT_KEY|KEY_NORMALIZE --key_type ShortText --default_tokenizer TokenBigram
column_create --table Index --name index_bigram --flags COLUMN_INDEX|WITH_POSITION|WITH_SECTION --type test --source title,text
以下の設定がおのおの何を意味をしているのか、
--flags COLUMN_INDEX|WITH_POSITION|WITH_SECTION
あまり正しく理解していなかったので、勉強がてらまとめ直すことにします。
ちなみにマニュアルのこちらで軽ーく触れられています。
WITH_POSION
ワードの出現の位置をインデックスに保有します。
よって、フレーズ検索などをおこなう時にも有効です。
日本語のデータでトークナイザーをNgramに指定した場合は必須になります。
WITH_SECTION
文章全体ではなく、ブロッキングされているという前提でインデックスを作ります。
上記のsample.ddlの場合はあるワードが"title"もしくは"text"で出現したのかという情報を保有します。
なので、単一のカラムに対しては意味をなさないです。
WITH_WEIGHT
本件とは関係がないので、解説しません。
複数カラムへのインデックス
あとで記述
インデックス名を指定した検索
match_columns関数においてインデックス名を指定して検索することができる機能です。
この機能を用いると、同じカラムに対して異なるトークナイザーのインデックスを指定するなどが出来ます。
例えば、以下の例ですと
Blogテーブルのtitleカラムに対して、トークナイザーをMecabとBigramで指定します。
table_create --name Blog --flags TABLE_HASH_KEY --key_type ShortText
column_create --table Blog --name title --flags COLUMN_SCALAR --type ShortText
table_create --name IndexBigram --flags TABLE_PAT_KEY|KEY_NORMALIZE --key_type ShortText --default_tokenizer TokenBigram
column_create --table IndexBigram --name index_blog --flags COLUMN_INDEX|WITH_POSITION|WITH_SECTION --type Blog --source title
table_create --name IndexMecab --flags TABLE_PAT_KEY|KEY_NORMALIZE --key_type ShortText --default_tokenizer TokenMecab
column_create --table IndexMecab --name index_blog --flags COLUMN_INDEX|WITH_POSITION|WITH_SECTION --type Blog --source title
load --table Blog
[
{"_key":"grn1","title":"東京都"},
{"_key":"grn2","title":"京都府"},
{"_key":"grn3","title":"京都大学"}
]
Blogテーブルのtitleカラムに対して「京都」をいうワードで全文検索を行いますが、指定したインデックスによって異なる結果を返却することが分かります。
select --table Blog --query "京都" --match_columns IndexMecab.index_blog
[[0,1418640224.95989,0.0626418590545654],[[[1],[["_id","UInt32"],["_key","ShortText"],["title","ShortText"]],[2,"grn2","京都府"]]]]
select --table Blog --query "京都" --match_columns IndexBigram.index_blog
[[0,1418640246.23825,0.056649923324585],[[[3],[["_id","UInt32"],["_key","ShortText"],["title","ShortText"]],[1,"grn1","東京都"],[2,"grn2","京都府"],[3,"grn3","京都大学"]]]]
インデックスに対して重みを付けて検索する
インデックスを指定して検索が出来るのと同時に、インデックスに対して重みを付けて検索が出来ます。
上記で作成したBlogテーブルを用いて解説します。
まず、新たに_scoreというスコア値を保有するカラムを出力してみます。
select --table Blog --query "京都" --match_columns IndexMecab.index_blog --output_columns *,_score
[[0,1418641006.92207,0.000437021255493164],[[[1],[["title","ShortText"],["_score","Int32"]],["京都府",1]]]]
select --table Blog --query "京都" --match_columns IndexBigram.index_blog --output_columns *,_score
[[0,1418641022.63525,0.000339031219482422],[[[3],[["title","ShortText"],["_score","Int32"]],["東京都",1],["京都府",1],["京都大学",1]]]]
Mecab、Bigramともにスコアが1です。
これらに重み付けをして検索してみます。
ここでは、MecabでHITしたカラムを優先させたいため、Mecabのインデックスのスコアを10倍にします。
select --table Blog --query "京都" --match_columns IndexMecab.index_blog*10||IndexBigram.index_blog*1 --output_columns *,_score
[[0,1418641101.76831,0.000390052795410156],[[[3],[["title","ShortText"],["_score","Int32"]],["京都府",11],["東京都",1],["京都大学",1]]]]
「京都府」というカラムのスコアが11になっていることが分かります。
Mecabのスコア1が10倍となって10、それにBigramの1が加算されてスコアが11となるためです。
以上、12月11日のGroonga読書会で学んだことのうち、マニュアルに記載がない部分を中心にまとめました。
随時加筆修正していく予定です。