事象
RailsとElasticsearchで検索機能をつくり色々試してみる - その1:サンプルアプリケーションの作成を参考にRailsでElasticSearchの学習をしています。
インデックスとモデルの準備をして、いざインデックスを作成しようとしたら、下記のようなエラーが発生しました。
irb(main):001:0> Manga.create_index!
Traceback (most recent call last):
2: from (irb):1
1: from app/models/concerns/manga_searchable.rb:50:in `create_index!'
Elasticsearch::Transport::Transport::Errors::InternalServerError ([500] {"error":{"root_cause":[{"type":"class_cast_exception","reason":"class java.lang.String cannot be cast to class java.util.Map (java.lang.String and java.util.Map are in module java.base of loader 'bootstrap')"}],"type":"class_cast_exception","reason":"class java.lang.String cannot be cast to class java.util.Map (java.lang.String and java.util.Map are in module java.base of loader 'bootstrap')"},"status":500})
解決方法
解決方法はドキュメントタイプを指定することです。
app/models/xxx.rb
module XXXSearchable
extend ActiveSupport::Concern
included do
include Elasticsearch::Model
# ...省略...
# ドキュメントタイプの指定が必須
document_type "es_xxx_#{Rails.env}"
end
end
同様のIssueが上がっていたので、こちらをみて解決できました。
古いバージョン(6系までのもの)のgemではマッピング時にtypeとdocument_typeを推測していたのに対し、7系からはtypeとdocument_typeの推測をしなくなったため、というのが原因のようです。
そもそもドキュメントタイプとは
Elasticsearchでは、格納する1つの文章の単位をドキュメントと呼びます。
はじめての Elasticsearch - Qiitaの表現を借りると、RDBMSのレコードに相当するのがドキュメントということになります。
そして、ドキュメントタイプとは「ドキュメントの名」のことです。
"タイプ"という文言が含まれるので、型っぽく感じられますが、実体は「名前」です。
ちょっと困惑しがちなポイントですね。