Nigel
Nigel

Reputation: 1027

How to fix "Illegal Argument Exception" when creating an Elasticsearch index for a Rails model?

I'm trying to integrate Elasticsearch in my rails application. The problem comes when I try to do an import on my model. Video.__elasticsearch__.import.

So, in rails console, I ran Video.__elasticsearch__.import. I get this error: myflix_development does not exist to be imported into. Use create_index! or the :force option to create it.

I then ran Video.__elasticsearch__.create_index! and Video.__elasticsearch__.create_index!(force: true) and they both returned the same error of illegal argument exception:

 PUT http://localhost:9200/myflix_development [status:400, request:0.027s, query:N/A]
2019-06-08 11:18:29 +0800: > {"settings":{},"mappings":{"_doc":{"properties":{}}}}
2019-06-08 11:18:29 +0800: < {"error":{"root_cause":[{"type":"illegal_argument_exception","reason":"The mapping definition cannot be nested under a type [_doc] unless include_type_name is set to true."}],"type":"illegal_argument_exception","reason":"The mapping definition cannot be nested under a type [_doc] unless include_type_name is set to true."},"status":400}

I understand that I am supposed to create an elasticsearch index when I try to do an import but I'm getting this illegal argument exception which I am puzzled about

This is what I've done to set things up:

1) Included the gems in my gemfile:

gem 'elasticsearch-model'
gem 'elasticsearch-rails'

2) Included an initializer: app/config/initializers/elasticsearch.rb

Elasticsearch::Model.client =
  if Rails.env.staging? || Rails.env.production?
    Elasticsearch::Client.new url: ENV['SEARCHBOX_URL']
  elsif Rails.env.development?
    Elasticsearch::Client.new log: true
  else
    Elasticsearch::Client.new
  end

3) Included elasticsearch in my Video model

class Video < ActiveRecord::Base
  include Elasticsearch::Model
  index_name ["myflix", Rails.env].join("_")
  ...
end

4) Gemfile.lock

 elasticsearch (7.1.0)
      elasticsearch-api (= 7.1.0)
      elasticsearch-transport (= 7.1.0)
    elasticsearch-api (7.1.0)
      multi_json
    elasticsearch-model (6.0.0)
      activesupport (> 3)
      elasticsearch (> 1)
      hashie
    elasticsearch-rails (6.0.0)
    elasticsearch-transport (7.1.0)
      faraday
      multi_json

Any help will be appreciated!

Edit 1) Attempted to do a manual mapping in my model

class Video < ActiveRecord::Base
    include Elasticsearch::Model

    settings index: { number_of_shards: 1 } do
    mappings dynamic: 'false' do
      indexes :title, type: 'text'
      indexes :description, type: 'text'
    end
  end
...
end

Upvotes: 2

Views: 4328

Answers (3)

Akash Roy
Akash Roy

Reputation: 458

The "illegal argument exception" is getting occurred because ElasticSearch engine is failing to analyze a reserved keyword. Properties is considered the root field inside the mapping section.Reform the request as below by excluding the "_doc" keyword :

PUT {INDEX_NAME} {"settings":{},"mappings":{"properties":{}}}}

Upvotes: 0

Merus
Merus

Reputation: 8984

You can explicitly define the document type that elasticsearch-model passes to Elasticsearch by setting document_type. For instance:

class Video < ActiveRecord::Base
  include Elasticsearch::Model
  index_name ["myflix", Rails.env].join("_")
  document_type "video"
  ...
end

What name you use is arbitrary. As long as it's not _doc, you shouldn't run into this error on v7 and up.

Upvotes: 4

Pierre-Nicolas Mougel
Pierre-Nicolas Mougel

Reputation: 2279

From the error you have, I think you are using elasticsearch 7. The type _doc is specified in your index query but types are deprecated since es7.

You can try to update your elasticsearch library to match es7 or as suggested in the error message, you can use the parameter include_type_name in the mapping.

Upvotes: 0

Related Questions