Change elasticsearch mappings in rails!

To change mappings and reindex elasticsearch data with zero downtime:

  • Create an alias that using to search for model (this point to whatever index we want)
  • Point this alias to old index (avoid app crash when code change)
  • Create new index + import data to this index
  • Point our alias to new index
  • Delete old index
# Add alias user_docs to users index
curl -XPUT 'localhost:9200/users/_alias/user_docs?pretty'
curl -XGET 'localhost:9200/user_docs/_search' # Test if working

# create new users_v1 index
curl -XPUT 'localhost:9200/users_v1'

# Import
 User.import index: 'users_v1', type: 'user', force:true
 rake environment elasticsearch:import:model CLASS='User' INDEX='users_v1' FORCE=y

# Add alias to users_v1 index
curl -XPUT 'localhost:9200/users_v1/_alias/user_docs?pretty'

# one command
curl -XPOST localhost:9200/_aliases -d '
        {
            "actions": [
                { "remove": {
                    "alias": "user_docs",
                    "index": "users"
                }},
                { "add": {
                    "alias": "user_docs",
                    "index": "users_v1"
                }}
            ]
        }'

# Delete old data index
curl -XDELETE 'localhost:9200/users'

# Callback reindex when data change
 User.last.__elasticsearch__.index_document refresh: true, index: 'users_v1'

# Change index search in search query
class User
  def self.search_user()
    # ....
    return __elasticsearch__.search(search_definition, {index: 'user_docs'})
  end
end

Reference:

Tagged with rails