Groongaで複数のトークナイザを使い分ける方法
はじめに
全文検索エンジン Groonga を使っていると、トークナイザによる検索結果の違いを比較したくなる時があります。
しかし、検索時に利用するインデックスを明示的に指定する方法は、現時点ではドキュメント化されていないようです。
執筆中です。
いろいろと試した結果、同じテーブルに対して複数のトークナイザによるインデックスを作成し、select時に使い分ける方法がわかったのでまとめておきます。なお、対象のバージョンは執筆時点で最新の 3.0.7 です。
利用するスキーマ
Blogテーブルの検索結果を、TokenBigram
とTokenMecab
の2種類のトークナイザで比較するケースを考えます。
検索対象のテーブル「Blog」
title
とbody
カラムを持ちます。
table_create --name Blog --flags TABLE_HASH_KEY \ --key_type ShortText column_create --table Blog --name title --type ShortText column_create --table Blog --name body --type ShortText
Bigramによる索引テーブル「BigramTerms」
Blog
のtitle
とbody
に対して、TokenBigram
で索引blog_index
を作ります。
table_create --name BigramTerms \ --flags TABLE_PAT_KEY|KEY_NORMALIZE \ --key_type ShortText --default_tokenizer TokenBigram column_create --table BigramTerms --name blog_index \ --flags COLUMN_INDEX|WITH_POSITION|WITH_SECTION \ --type Blog --source title,body
Mecabによる索引テーブル「MecabTerms」
Blog
のtitle
とbody
に対して、TokenMecab
で索引blog_index
を作ります。
table_create --name MecabTerms \ --flags TABLE_PAT_KEY|KEY_NORMALIZE \ --key_type ShortText --default_tokenizer TokenMecab column_create --table MecabTerms --name blog_index \ --flags COLUMN_INDEX|WITH_POSITION|WITH_SECTION \ --type Blog --source title,body
検索時にインデックスを指定する方法
以下のように--match_columns
にインデックス名を指定することで、インデックスを使い分けることができます。
BigramTermsで検索したい場合:
select --table Blog --match_columns BigramTerms.blog_index \ --query foo
MecabTermsで検索したい場合:
select --table Blog --match_columns MecabTerms.blog_index \ --query foo
なお、以下のようにカラム名だけを指定した場合は、どちらかのインデックスが使われるようですが、そのルールは不明です。
select --table Blog --match_columns 'title || body' --query foo
重み付けしたい場合
このようにしてインデックスを使い分けることができますが、カラムによって重み付けしたい場合があります。通常であれば、--match_columns 'title * 5 || body'
のようにしてtitle
を重視するといったことができますが、インデックスを明示したい場合はそうはいきません。
最初は --match_columns 'BigramTerms.blog_index.title * 5 || BigramTerms.blog_index.body'
としたらできるかと思いましたが、これは --match_columns 'title * 5 || body'
と同じ意味になりうまくいきません。
解決策としては、以下のようにカラムごとに別々のインデックスを作成します。
table_create --name BigramTerms \ --flags TABLE_PAT_KEY|KEY_NORMALIZE \ --key_type ShortText --default_tokenizer TokenBigram column_create --table BigramTerms --name blog_title \ --flags COLUMN_INDEX|WITH_POSITION|WITH_SECTION \ --type Blog --source title column_create --table BigramTerms --name blog_body \ --flags COLUMN_INDEX|WITH_POSITION|WITH_SECTION \ --type Blog --source body
そして、 --match_columns 'BigramTerms.blog_title * 5 || BigramTerms.blog_body'
とすることで、インデックスを明示し、かつ重み付けした検索が可能になります。