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.
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.