ruby-on-railselasticsearchelasticsearch-model

Save specific fields with elasticsearch-model in Rails


I'm using elasticsearch-model gem in a Rails 4 project to store my Users in MySQL and Elasticsearch. In my project, the Elasticsearch part is used to find people with some of the MySQL fields like geo_point, birthdate, gender, etc... But not every fields I've in MySQL "users" table are useful for user's search.

So, I'd like to store ALL users fields in MySQL and only fields needed for user's search in Elasticsearch.

To store only required fields on create, I've overrided the method 'as_indexed_json' and used :

as_json(only: ['id', 'gender', 'location']

On create, things work great. But when I'm updating a user with fields that should be saved in MySQL only, it adds it to Elasticsearch anyway.

For instance, my User model have "id", "gender", "is_premium", "status", "created_at", "birthdate", "location". In Elasticsearch I'd like to save only "id", "gender", "birthdate", "location"

How can I do this? Thanks for your help.


Solution

  • This is an issue with elasticsearch-rails (see github).

    In a nutshell the default update callback calls update_document which doesn't use as_indexed_json: it uses ActiveModel::Dirty to only send the changed columns.

    You can fix this either by overriding the update_document method so that it only includes what you want, or by changing what the callback does, for example

    after_commit on: [:create, :update] do
      index_document
    end
    
    after_commit on: [:destroy] do
      delete_document
    end
    

    instead of using the default callbacks module will result in index_document being used, which always does a 'dumb' full update rather than trying to only send the deltas.