はじめに
Elasticsearchのデータタイプのうち文字列系のtextとkeywordについて、それぞれを選択した場合の詳細Mapping設定での設定可能プロパティを表にして、これらの違いから、textとkeywordのデータタイプ自体の理解を深めることにしました。
文字列系データタイプのtextとkeyword について
この記事を書いている今日現在のElasticsearchの最新バージョンは6.5です。
Elasticsearchは伸び代のあるソフトウェアということもあり、バージョンごとに仕様が変わることもしばしばのようです。
文字列系の項目のデータタイプとしては、ver 6.xでは text、keywordの2種類があります。過去にはstringというものだったようです。*1
雑に言うと、textは言語解析ありの全文検索用、keywordはtermでの検索(なんと言えば良いのか、コード値で厳格にヒットさせるような検索)用です。
特に根拠もなく、中の人にきいたわけでもないですが、これからはtextとkeywordの2種類でいくのではないでしょうか。
なお、Mapping設定で特に指定しなくともver 6.xの現在では、同じフィールドに関して、textタイプとkeywordタイプの両方のデータがインデックスに登録されるようなので、ざっくり使いたい時はあまり気にしなくても良いかもしれません。
一方、混みいった設定をする場合やそもそも設計を明確にするため、様々な理由で明示的にtextかkeywordか設定する場合には、さらなるオプション設定を行うことになります。
例えば、
// 中略 "type":"text", "analyzer":"kuromoji", "fielddata":true, // 中略
のような塩梅です。
そしてこの追加のオプション設定のプロパティですが、設定シンタックス等は末尾にURL引用の公式Rのページをご覧いただくこととして、オプションの数がなかなかの数あって、結構悩ましいです。
デフォルト(何も個別に指定しない)でも良いケースが大半だと思いますが、そんなことは忘れて、雑にいろいろやっていると突然あるクエリーの発行時に、textタイプでこのクエリーを使うなら、XXXオプションを設定してくださいとエラーを食らうことになります。
ということで、もやもやを解消するために、両者の設定可能プロパティをマルバツにしてみました。
textとkeywordデータタイプの設定可能プロパティ
並べてみると、数に圧倒されそうになる一方で、文字列の検索ならtextとkeyword両方に対応しているもの、textだけのもの、keywordだけのものが色分けされて、個人的にはスッキリしました。
各プロパティの意味をある程度理解する必要はありますが、こうやってみると、片方だけ対応しているものは、そのデータタイプに見合ったオプションになっているようですね。 当たり前といえば当たり前ですが、逆に言うと、このオプションが必要になる・意味があるのがtext、はたまたkeywordであるという理解の仕方もあるのではと思いました*2。
textとkeywordデータタイプ の公式Rへのリンク
textとkeywordデータタイプの設定可能プロパティ(コピペ用のテキストでの再掲)
項番 | 設定プロパティ | 設定事項 | text | keyword |
---|---|---|---|---|
1 | index | 検索対象とするかの設定 | ◯ | ◯ |
2 | ignore_above | この値を超える桁数のデータはインデックスに格納しない | ー | ◯ |
3 | store | trueに設定した場合、_source領域に保持しない(が、stored_fieldに個別に保持する...のでそこから取り出せる) | ◯ | ◯ |
4 | fields | 一つのフィールドに複数設定を適用(例. 英語とフランス語のそれぞれのアナライザーを指定した内部フィールドを2つ用意。←このような用途の際に派生フィールドを作る必要がない) | ◯ | ◯ |
5 | similarity | 類似度の計算アルゴリズムを指定(デフォルトはBM25) | ◯ | ◯ |
6 | boost | ブースト | ◯ | ◯ |
7 | norms | スコアリングでフィールドの長さを考慮 | ◯ | ◯ |
8 | analyzer | アナライザー | ◯ | ー |
9 | search_analyzer | 検索時にインデックスと異なるアナライザーを使う場合に設定 | ◯ | ー |
10 | search_quote_analyzer | 要確認(ひとまず、search_analyzerの設定と同じものがデフォルトらしい) | ◯ | ー |
11 | normalizer | ノーマライズするか | ー | ◯ |
12 | index_options | ポジション情報などをインデックスに格納して検索やハイライトに対応しやすくする | ◯ | ◯ |
13 | eager_global_ordinals | terms aggsの利用頻度が高いならtrueに設定すると良い | ◯ | ◯ |
14 | index_prefixes | 最初の数桁を個別領域に格納して、prefix searchの効率向上 | ◯ | ー |
15 | position_increment_gap | 説明略 | ◯ | ー |
16 | index_phrases | 2コイチワーズを個別領域に格納してフレーズ検索を効率化 | ◯ | ー |
17 | term_vector | アナライズ対象フィールドのterm vectorsの値をインデックスに格納するか | ◯ | ー |
18 | fielddata | sortやaggsのためにメモリに値を確保するか(text用) | ◯ | ー |
19 | fielddata_frequency_filter | fielddata設定のさらなるチューニング | ◯ | ー |
20 | doc_values | sortやaggsのためにディスクに値を確保するか(keywrod用) | ー | ◯ |
21 | null_value | 値がない場合にNULL値を明示的に保持 | ー | ◯ |
22 | split_queries_on_whitespace | 検索語をスペースで分割して複数ワードとして検索するか(合ってるかな...?) | ー | ◯ |