私の環境
Mac OSX yosemite
Ruby 2.2.2
Rails 4.2.1
elasticsearch-modelを使ってElasticsearchのindexを作ったとき、create_index!をすればindexは作られるのだけれど、そのときに作られるmapping情報が該当modelのもの以外が登録できないため、検索が全然うまくできないという症状の悩まされてました。
Web+DB pressの87号のElasticsearchをRubyで、の記事を読んでも、どうもイメージ的にはindexをテーブルのように扱っているような気がしてなりません…(記事の中での説明ではそう書いてはないけれど、後半の扱いがそんな感じに思えました)。
Elasticsearchのキーワードをデータベース風にいうと、
- Elasticsearchのindex
- データベース
- Elasticsearchのtype
- テーブル
- Elasticsearchのdocument
- 行
- Elasticsearchのmapping
- (DBの)インデックス
ということだったと思うので、indexは一度作って、あとはtype毎のmapping情報を追加してからdocumentを登録するのが正しいんじゃないかなーと思っていたのですが、どうもmappingだけをサクッと登録するようなのはelasticsearch-modelにはなさそうでした。あってもいいと思うんだけれど…。
そこで、type毎にmappingだけ登録する方法はないのかな?と思ってelasticsearchの本家の情報を調べていたら、ありました。
参考リンク:Put Mapping
これならあるんじゃないのかなーと思って調査していたら、elasticsearch-rubyの中にそれらしきコードがありました。できるんだったらこれを呼び出せばいいわけです。
参考リンク:elasticsearch-ruby: put_mapping.rb
ということで、以下のようにしてみました。
class Shop < Activerecord::Base include Elasticsearch::Model # index_nameは省略 settings index: { # 省略 } do mapping do # 省略 end end def self.put_mapping __elasticsearch__.client.indices.put_mapping( index: index_name, type: document_type, body: mapping ) end end
これで、create_index!を実行したmodel以外のmodelのmapping情報は、put_mappingを呼び出せば行えます。ちゃんとmappingが登録されたかどうかの確認は、例えばrails consoleで以下のようにすればOKです。
Shop.__elasticsearch__.client.indices.get_mapping(index: index_name)
あとはデータをimportすればOKです。
もっと他にいい方法がありましたら教えていただけると助かります!!