I'm trying to write specs for elastic search, my production stack is : Ruby 2.3.1, rails 5.0.3, hosted elastic search cluster (cloud.elastic.co).
Situation
When indexing documents in the hosted cluster, some indexes attributes are added, for instance, if I index the name of my Building (Rails model) instance, there will be a name and a 'name.keyword' in the indexed document.
Problem
I used https://github.com/elastic/elasticsearch-ruby/tree/master/elasticsearch-extensions#testcluster to create a test cluster before my rspec suite, and installed elasticsearch 6.2.4 using Homebrew (brew install elasticsearch
) on my OSX.
Then I started writing specs, in my controller action, I sort by name.keyword
so that the query looks like
{
query: {
sort: {
name: { order: :asc}
}
}
}
I get an error at this point.
Error
...
Failure/Error: response.headers["count"] = buildings.response.hits.total
Elasticsearch::Transport::Transport::Errors::BadRequest:
[400] {"error":{"root_cause":[{"type":"query_shard_exception","reason":"No mapping found for [name.keyword] in order to sort on","index_uuid":"XXqX1-GCQbaHDkhHeTZS5Q","index":"buildings"}],"type":"search_phase_execution_exception","reason":"all shards failed","phase":"query","grouped":true,"failed_shards":[{"shard":0,"index":"buildings","node":"INMaKXXNT5S26JBjhTHUqw","reason":{"type":"query_shard_exception","reason":"No mapping found for [name.keyword] in order to sort on","index_uuid":"XXqX1-GCQbaHDkhHeTZS5Q","index":"buildings"}}]},"status":400}
Shared Example Group: "authentication" called from ./spec/controllers/user_api/v1/buildings_controller_spec.rb:5
# /Users/Thomas/.rvm/gems/ruby-2.3.1/gems/elasticsearch-transport-5.0.5/lib/elasticsearch/transport/transport/base.rb:202:in `__raise_transport_error'
# /Users/Thomas/.rvm/gems/ruby-2.3.1/gems/elasticsearch-transport-5.0.5/lib/elasticsearch/transport/transport/base.rb:319:in `perform_request'
# /Users/Thomas/.rvm/gems/ruby-2.3.1/gems/elasticsearch-transport-5.0.5/lib/elasticsearch/transport/transport/http/faraday.rb:20:in `perform_request'
# /Users/Thomas/.rvm/gems/ruby-2.3.1/gems/elasticsearch-transport-5.0.5/lib/elasticsearch/transport/client.rb:131:in `perform_request'
...
The main part of the error : "reason":"No mapping found for [name.keyword] in order to sort on"
Hypothesis
- 1/ I need to write the mapping myself, and provide the field name.keyword, but I'm unsure how to do this
- 2/ I should use a hosted test cluster to replicate the same behavior
I think 1/ may be the way to go, but elasticsearch guides are difficult to read when talking about their gems, and I haven't been able to do so. 2/ is of course easier but I'm wondering if it won't lead to more problems in the long term (performance, etc.)
Documentation
https://medium.com/@rowanoulton/testing-elasticsearch-in-rails-22a3296d989 https://github.com/elastic/elasticsearch-rails/issues/69
Any idea is welcomed !