はてだBlog(仮称)

私的なブログど真ん中のつもりでしたが、気づけばWebサイト系のアプリケーション開発周りで感じたこと寄りの自分メモなどをつれづれ述べています。2020年6月現在、Elasticsearch、pandas、CMSなどに関する話題が多めです。...ですが、だんだんとより私的なプログラムのスニペット置き場になりつつあります。ブログで述べている内容は所属組織で販売している製品などに関するものではなく、また所属する組織の見解を代表するものではありません。

Elasticsearchのマッピングについての自分的まとめ

はじめに

Elastisearchのマッピングの設定についてまとめてみた。 ここでは、typeやanalyzerなど他で詳しくとりまとめされているサイトがあるものは割愛し、その他の設定プロパティや、Dynamic Mapping(ダイナミックマッピング)、Index Template(インデックステンプレート)、インデックスの型定義に該当するマッピングの関係などを中心にまとめてみた。

マッピング(mappings)とは

現在のElasticsearchのバージョン(6.x)だと、インデックスはRDBのテーブル、マッピングはCREATE TABLE文と言ってもよかろう。

マッピングの設定構文(イメージ)

f:id:azotar:20181122005730p:plain

  1. よく使うのは、type、format、analyzer(およびsearch_analyzer)、normalizer だと思われる。ただ、これらはここではあえて説明しない。
  2. 親子構造を持つドキュメントのmapping定義は、それに合わせた構文が存在。図中のプロパティ3-X関連のイメージ(ポイントはtype:nested)。
  3. Multi-Fieldという考え方で、形態素解析N-Gramを併用できる。fieldプロパティがポイント。
  4. dynamic プロパティで、Dyanamic Mappingのオンオフ切り替え。Dyanmic Mappingは次節参照。
  5. dynamicプロパティは、 配下に継承される。 ここで、_docでfalse設定し、配下のオブジェクトでtrueにするとそのオブジェクトはDynamic Mappingされる。
  6. 全部の組み合わせを調べたわけではないが、dynamicプロパティに限らず、マッピング設定は、上位のプロパティ名(最上位は"_doc")で指定しておけば、配下のプロパティにデフォルト値として継承されると思われる。 analyzerも同様。

otiai10.hatenablog.com

デフォルト値で設定しておき要件に応じて必要なら追加設定する(のが良いと思われる)プロパティ

  1. doc_values:false時に、検索に使われないかつメモリに載らないが、インデックスには保持する
  2. fielddata: typeが”text”の場合の、doc_values相当
  3. enabled: 検索に使われないが、インデックスには保持する
  4. ignore_above: 指定された文字数以上の場合、検索には使われない(ただし_sourceには保持)
  5. norms: 略
  6. copy_to: あるフィールドにコピーして保持する(例. 性フィールドと名フィールドを氏名フィールドに保持)。“store”も参照のこと。
  7. store: trueに設定した場合、検索クエリ時に”stored_fields”配列でフィールド名を指定すると、”source”によるものに比べると絞り込んだ検索フィールドを得られる。 (性能などは不明だが、source filteringのシンタックスシュガーの意味合いもあると解釈することにした。あと、”source”に保持されない、copy_to項目はこれを使うとのこと)
  8. coerce: 数字とみなせる文字列を数字として保持、浮動小数点を整数にして保持するかを設定
  9. ignore_malformed: typeがエラーになる場合は、このドキュメントをリジェクトする
  10. null_value: null値のインデックス化の扱いを指定
  11. positio_increment_gap: phrase queriesのヒットの仕方を微調整するためのオプション
  12. term_vector: デフォルトno。 yes(やwith_...)にすると、analysis時の解析情報等を保持する。特定の検索クエリではこの情報を必要とするものがある。
  13. eager_global_ordinals: その時がきたら勉強しよう...

設定の仕方、特徴など

  1. mappings構文を用いて、あるインデックスに対してPUTで指定する。
  2. RDBのCREATE TABLEになぞらえて説明したが、Elasticsearchでは、mappingsの指定が最初にされていなくても、インデックスにドキュメントを登録した際に、未知のフィールドが存在しても、自動で推測してそれなりの条件で登録してくれる。
  3. もちろんアドホックな管理で良い場合やそうせざるを得ない場合は自動で推測におまかせしてしまうのだろうけど、推測を誤ることふくめ痛し痒しなところもある。ここでは引用しないが、パフォーマンスの課題も出てくるだろう。
  4. mappings構文で指定しなくとも、この自動でフィールドを登録してくれる仕組みを dynamic mappingと製品では呼んでいるようだ。
  5. dynamic mappingには2つの設定の軸がある。
  6. ひとつはDynamic field mapping。これは、dynamic mappingについては、JSONのデータタイプによってよしなにElasticsearchのデータタイプを判定してくれるのだが、string型については、文字通り文字列を設定するもの以外に、日付(date)や数字が入るようなものについて、Date detection、Numeric detectionという考え方で、そもそも自動判定するか、自動判定する場合の日付とみなす形式はこれこれという設定を行う。
  7. Dynamic field mappingは、mappings構文で指定することに注意。
  8. もうひとつは Dynamic templates。名前のイメージどおりの機能でおそらく便利な仕組みだが、分量の都合でここでは割愛。
  9. さらに別の概念として、Index Templateというものがある。f:id:azotar:20181122005732p:plain これは、インデックステンプレートと呼ばれるmapping設定の型自体をElasticsearchに登録しておく。インデックステンプレートは、このテンプレートを適用する候補となるインデックスの名前を正規表現で指定して登録できる。この正規表現のインデックスに合致するようなインデックスにドキュメント登録される際に、インデックステンプレートで規定のmapping設定が適用される。設定のキモとなるプロパティは、"index_patterns"、"order"。昔は、「インデックステンプレート」という機能の概念名称にしたがい"template"プロパティで指定していたようだが、最近だと"index_patterns"が標準になっているようなので注意。

参考文献(公式サイトのリンク)

Dynamic Mapping | Elasticsearch Reference [6.5] | Elastic

Dynamic field mapping | Elasticsearch Reference [6.5] | Elastic

www.elastic.co