# groonga - An open-source fulltext search engine and column store.

- 日本語版はこちら

### Navigation

- index
- next |
- previous |
- Groonga v4.0.4-214-gb1aaec1 documentation »
- 4. Tutorial »

# 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 シークヮーサー)"という文字列に置換されてから検索されるため、表記の揺れを吸収して検索できるようになりました。

### Navigation

- index
- next |
- previous |
- Groonga v4.0.4-214-gb1aaec1 documentation »
- 4. Tutorial »