Today I Learned

Working with ElasticSearch and Rails; part 1

A typical setup for a Ruby on Rails app and Elasticsearch is built around the elasticsearch-model, elasticsearch-rails elasticsearch-persistence and elasticsearch-dsl bundle.

The above setup integrates well with the ActiveRecord, adding a convenient way to define indexes based on AR models, as well as providing a neat way to create and refresh them in “all go” and atomic way.

Typically you achieve so by iterating over your models and calling the following on each of them:

model_class.__elasticsearch__.create_index!(force: true)
model_class.__elasticsearch__.refresh_index!
model_class.import

The thing I learnt the hard way is that the default scope (used by other gems like acts_as_paranoid for instance) is not respected by the elasticsearch gem. Also it is very easy to get into the N+1 one problems if your field mappings go through your associations.

A remedy for this is to pass the scope to the import method call, like this:

model.import scope: 'for_es_import'

I typically define such scope per each indexed model, so all includes and default scopes are satisfied and I can iterate over a set of multiple indexed AR models easily.

Finally, if you need to work with multiple indexes based on the same model, you’ll achieve that so much easily using gem Chewy. From my experience it’s also a much easier ES wrapper gem to use, from the outside Rails environment (i.e you have to use it in a Sinatra app).