よしだのブログ

サブタイトルはありません。

Solr 風 Dynamic Mapping Template を作った。(Elasticsearch 1.3.2)

Elasticsearch で、Solr のデフォルトのスキーマに定義されているダイナミックフィールドを再現したかったので mapping ファイルを作ってみました。細かいテストはやっていませんが、多分うまくいくかと。

作った経緯。

Elasticsearch の特長的な機能の一つとして、フィールドを一切定義しなくてもデータを入れることのできる dynamic mapping があります。dynamic mapping は、初回にデータを投入した際に、フィールドの定義を自動的に行い、さらに投入したデータの中身によって、フィールドの型を推測して設定してくれます。注目されている kibana のようにログを保管して分析するソリューションの基板として使う場合、この機能は必須かと思います。この機能のありなしでは、導入までのハードルの高さが全然違うので。

一方、普通に検索エンジンとして使う、特にフィールド個別に詳細検索ができるようなケースの場合、型を推測する機能というのは100%正解するわけではないので、結局のところスキーマを定義することになると思います。

そこで思い出したのが、Solr の dynamic field の機能です。この dynamic field はフィールド名に、特定のプレフィックスやサフィックスがついていた場合、固定の型として新たにフィールドを作成するという機能です。例えば、_i で終わるフィールド名、count_i の場合は int して扱うということが出来ます。なので、普通に検索エンジンとして使う場合でも、特別に schema.xml をいちいち起こさなくてもすぐに使い出すことができます。この機能は、結構便利だし、型も確実なので個人的にはよく使っています。Elasticsearch でも dynamic template という機能で同じことができます。ただ、デフォルトでは定義されていなかったので、じゃあ作っちゃえとw

Customising dynamic mapping

環境

  • elasticsearch 1.3.2

内容

  • デフォルトスキーマの中でも daynamic フィールドのみを対象にしました。
  • その中でも以下は対象外です。
    • *_coordinate
    • *_p
    • *_ti などTrie系のもの
    • *_pi
    • *_c
    • ignored_*
    • attr_*
    • random_*
  • 以下は追加したものです。
    • *_u (unigram用)
    • *_ja (日本語形態素解析用 kuromoji 利用)
  • String (_s ss) と Text(*t *_txt) の動きが、Solr とはだいぶ違うので注意してください。それ以外の項目についても検証していないので、色々違う気がしますw

導入時の注意

  • kuromoji を指定しているので、あらかじめ kuromoji をインストールしておいてください。*1
  • 31行目にベタ書きでタイプ名 'article' が埋まっているので、好きなものに変えて使ってください。
  • blog というインデックスに、マッピングを登録するときの例は以下のとおり
    • POST /blog -D @mapping.js

テンプレート

Dynamic mapping template for Elasticsearch 1.3.2

参考

高速スケーラブル検索エンジン ElasticSearch Server

高速スケーラブル検索エンジン ElasticSearch Server

  • 作者: Rafal Kuc,Marek Rogozinski,株式会社リクルートテクノロジーズ,大岩達也,大谷純,兼山元太,水戸祐介,守谷純之介
  • 出版社/メーカー: KADOKAWA/アスキー・メディアワークス
  • 発売日: 2014/03/21
  • メディア: 大型本
  • この商品を含むブログ (2件) を見る

ついったー

*1:自分でやった時は、何故か plugin -i では素直に入らなかったので、ソースからビルドして入れました。→解決。proxy の指定が原因でした。次のように指定するとOKでした。https 先だとNGです。 set JAVA_OPTS=-Dhttp.proxyHost=xxx.xxx -Dhttp.proxyPort=8080 -Dhttps.proxyHost=xxx.xxx -Dhttps.proxyHost=8080