4.11. クエリ拡張¶
Groongaでは、 select コマンドにquery_expanderパラメータを指定することによって、ユーザが指定した検索文字列を適宜拡張することが可能です。
たとえば、ユーザが'シークヮーサー'という文字列で検索した場合に、'シークヮーサー OR シークァーサー'で検索した場合と同一の結果を返すことによって、本来ユーザが必要とする結果をよりもれなく検索できるようになります。
4.11.1. 準備¶
クエリ拡張機能を使用するためには、検索対象となる文書を格納するテーブル(ここでは文書テーブルと呼びます)以外に、ユーザの指定した検索文字列を置換するためのテーブル(ここでは置換テーブルと呼びます)を準備します。置換テーブルでは、その主キーが置換前の文字列となり、文字列型(ShortText)のカラムの値が置換後の文字列となります。
TODO: 文字列型のベクターカラムでも可能であり、その場合は各要素をORでつなげたものに置換されるということを記述する。
実際に文書テーブルと置換テーブルを作成してみましょう。
Execution example:
table_create Doc TABLE_PAT_KEY ShortText
# [[0, 1337566253.89858, 0.000355720520019531], true]
column_create Doc body COLUMN_SCALAR ShortText
# [[0, 1337566253.89858, 0.000355720520019531], true]
table_create Term TABLE_PAT_KEY|KEY_NORMALIZE ShortText --default_tokenizer TokenBigram
# [[0, 1337566253.89858, 0.000355720520019531], true]
column_create Term Doc_body COLUMN_INDEX|WITH_POSITION Doc body
# [[0, 1337566253.89858, 0.000355720520019531], true]
table_create Synonym TABLE_PAT_KEY ShortText
# [[0, 1337566253.89858, 0.000355720520019531], true]
column_create Synonym body COLUMN_SCALAR ShortText
# [[0, 1337566253.89858, 0.000355720520019531], true]
load --table Doc
[
{"_key": "001", "body": "すっぱいブドウと甘いシークァーサー"},
{"_key": "002", "body": "シークヮーサージュースとゴーヤチャンプル"},
]
# [[0, 1337566253.89858, 0.000355720520019531], 2]
load --table Synonym
[
{"_key": "シークァーサー", "body": "(シークァーサー OR シークヮーサー)"},
{"_key": "シークヮーサー", "body": "(シークァーサー OR シークヮーサー)"},
]
# [[0, 1337566253.89858, 0.000355720520019531], 2]
この例では、ユーザが"シークァーサー"と入力しても、"シークヮーサー"と入力しても、それぞれの異なる表記の文書をもれなく検索するための置換テーブルを作成しています。
4.11.2. 検索¶
それでは実際に、準備した置換テーブルを使ってみましょう。まずは、query_expanderパラメータを指定せずにselectコマンドを使って検索してみます。
Execution example:
select Doc --match_columns body --query "シークァーサー"
# [
# [
# 0,
# 1337566253.89858,
# 0.000355720520019531
# ],
# [
# [
# [
# 1
# ],
# [
# [
# "_id",
# "UInt32"
# ],
# [
# "_key",
# "ShortText"
# ],
# [
# "body",
# "ShortText"
# ]
# ],
# [
# 1,
# "001",
# "すっぱいブドウと甘いシークァーサー"
# ]
# ]
# ]
# ]
select Doc --match_columns body --query "シークヮーサー"
# [
# [
# 0,
# 1337566253.89858,
# 0.000355720520019531
# ],
# [
# [
# [
# 1
# ],
# [
# [
# "_id",
# "UInt32"
# ],
# [
# "_key",
# "ShortText"
# ],
# [
# "body",
# "ShortText"
# ]
# ],
# [
# 2,
# "002",
# "シークヮーサージュースとゴーヤチャンプル"
# ]
# ]
# ]
# ]
指定された文字列に完全に一致するレコードのみがそれぞれヒットします。次に、query_expanderパラメータに、準備したSynonymテーブルのbodyカラムを指定してみましょう。
Execution example:
select Doc --match_columns body --query "シークァーサー" --query_expander Synonym.body
# [
# [
# 0,
# 1337566253.89858,
# 0.000355720520019531
# ],
# [
# [
# [
# 2
# ],
# [
# [
# "_id",
# "UInt32"
# ],
# [
# "_key",
# "ShortText"
# ],
# [
# "body",
# "ShortText"
# ]
# ],
# [
# 1,
# "001",
# "すっぱいブドウと甘いシークァーサー"
# ],
# [
# 2,
# "002",
# "シークヮーサージュースとゴーヤチャンプル"
# ]
# ]
# ]
# ]
select Doc --match_columns body --query "シークヮーサー" --query_expander Synonym.body
# [
# [
# 0,
# 1337566253.89858,
# 0.000355720520019531
# ],
# [
# [
# [
# 2
# ],
# [
# [
# "_id",
# "UInt32"
# ],
# [
# "_key",
# "ShortText"
# ],
# [
# "body",
# "ShortText"
# ]
# ],
# [
# 1,
# "001",
# "すっぱいブドウと甘いシークァーサー"
# ],
# [
# 2,
# "002",
# "シークヮーサージュースとゴーヤチャンプル"
# ]
# ]
# ]
# ]
どちらのクエリ文字列も、"(シークァーサー OR シークヮーサー)"という文字列に置換されてから検索されるため、表記の揺れを吸収して検索できるようになりました。