.. -*- rst -*-

.. highlightlang:: none

.. groonga-command
.. database: tutorial-query-expansion

クエリ拡張
==========

groongaでは、 :doc:`/commands/select` コマンドにquery_expansionパラメータを指定することによって、ユーザが指定した検索文字列を適宜拡張することが可能です。

たとえば、ユーザが'シークヮーサー'という文字列で検索した場合に、'シークヮーサー OR シークァーサー'で検索した場合と同一の結果を返すことによって、本来ユーザが必要とする結果をよりもれなく検索できるようになります。

準備
----

クエリ拡張機能を使用するためには、検索対象となる文書を格納するテーブル(ここでは文書テーブルと呼びます)以外に、ユーザの指定した検索文字列を置換するためのテーブル(ここでは置換テーブルと呼びます)を準備します。置換テーブルでは、その主キーが置換前の文字列となり、文字列型(ShortText)のカラムの値が置換後の文字列となります。

TODO: 文字列型のベクターカラムでも可能であり、その場合は各要素をORでつなげたものに置換されるということを記述する。

実際に文書テーブルと置換テーブルを作成してみましょう。

.. groonga-command
.. include:: ../example/tutorial/query_expansion-1.log
.. table_create Doc TABLE_PAT_KEY ShortText
.. column_create Doc body COLUMN_SCALAR ShortText
.. table_create Term TABLE_PAT_KEY|KEY_NORMALIZE ShortText --default_tokenizer TokenBigram
.. column_create Term Doc_body COLUMN_INDEX|WITH_POSITION Doc body
.. table_create Synonym TABLE_PAT_KEY ShortText
.. column_create Synonym body COLUMN_SCALAR ShortText
.. load --table Doc
.. [
.. {"_key": "001", "body": "すっぱいブドウと甘いシークァーサー"},
.. {"_key": "002", "body": "シークヮーサージュースとゴーヤチャンプル"},
.. ]
.. load --table Synonym
.. [
.. {"_key": "シークァーサー", "body": "(シークァーサー OR シークヮーサー)"},
.. {"_key": "シークヮーサー", "body": "(シークァーサー OR シークヮーサー)"},
.. ]

この例では、ユーザが"シークァーサー"と入力しても、"シークヮーサー"と入力しても、それぞれの異なる表記の文書をもれなく検索するための置換テーブルを作成しています。

検索
----

それでは実際に、準備した置換テーブルを使ってみましょう。まずは、query_expansionパラメータを指定せずにselectコマンドを使って検索してみます。

.. groonga-command
.. include:: ../example/tutorial/query_expansion-2.log
.. select Doc --match_columns body --query "シークァーサー"
.. select Doc --match_columns body --query "シークヮーサー"

指定された文字列に完全に一致するレコードのみがそれぞれヒットします。次に、query_expansionパラメータに、準備したSynonymテーブルのbodyカラムを指定してみましょう。

.. groonga-command
.. include:: ../example/tutorial/query_expansion-3.log
.. select Doc --match_columns body --query "シークァーサー" --query_expansion Synonym.body
.. select Doc --match_columns body --query "シークヮーサー" --query_expansion Synonym.body

どちらのクエリ文字列も、"(シークァーサー OR シークヮーサー)"という文字列に置換されてから検索されるため、表記の揺れを吸収して検索できるようになりました。
