user2037696
user2037696

Reputation: 1105

Automatically update index with elasticsearch-rails

I'm implementing the completion suggester using the elasticsearch-rails gem. Everything works except update or delete.

For example when I update the title of an article and try to research again, the same title still exist.

I have included Elasticsearch::Model::Callbacks

Model:

require 'elasticsearch/model'

class Article < ActiveRecord::Base
  include Elasticsearch::Model
  include Elasticsearch::Model::Callbacks

  def self.suggest(query)
    Article.__elasticsearch__.client.suggest(:index => Article.index_name, :body => {
        :suggestions => {
            :text => query,
            :completion => {
                :field => 'suggest'
            }
        }
    })
  end

 settings :index => { :number_of_shards => 1 } do
   mappings :dynamic => 'false' do
     indexes :title, :type => 'string', :analyzer => 'english'
     indexes :suggest, :type => 'completion', :index_analyzer => 'simple', :search_analyzer =>       'simple', :payloads => true
   end
  end

  def as_indexed_json(options={})
    {
        :name => self.title,
        :suggest => {
            :input => [self.title, self.content],
            :output => self.title,
            :payload => {
                :id => self.id,
                :content => self.content
            }
        }
    }
  end
end

Controller:

class ArticlesController < ApplicationController
  def update
    @article = Article.find(params[:id])

    if @article.update_attributes(article_params)
       render :json => @article
    else
       render :json => @article.errors
    end
  end
  # ...
end

Upvotes: 4

Views: 2677

Answers (1)

Saskia Vola
Saskia Vola

Reputation: 191

we had that same problem.

The only way to change the autocompletion data is to call the optimize API. Optimize will cause a segment merge. Completion suggesters are stored in their own datastructure calles FST. They are not part of the regular index, so just refreshing would not work. The datastructure used to store completion suggestions is only created at index time, when a new segment is written. All the old data will be available until a full cleanup happens, which is only guaranteed when segments are merged.

So call optimize:

http://localhost:9200/indexName/_optimize?max_num_segments=number_of_segments

http://www.elasticsearch.org/guide/en/elasticsearch/guide/current/merge-process.html#optimize-api

The smaller the number of segments the more performant completion will be.

And then check again. For me it worked!

Optimizing is slow and I/O heavy, so you cannot run it all the time, but maybe once a day or so...

Good luck!

https://groups.google.com/forum/?fromgroups#!searchin/elasticsearch/completion$20suggester$20delete/elasticsearch/8Rfg4kGV0ps/YG0V9jM7JhcJ

http://www.elasticsearch.org/blog/you-complete-me/

Upvotes: 3

Related Questions