Создайте индекс с новыми параметрами searchkick в консоли rails - PullRequest
2 голосов
/ 06 мая 2019

Я ищу способ беспрепятственного обновления моего индекса Elasticsearch.

Я переезжаю из:

class Product < ApplicationRecord
  searchkick
end

Кому:

class Product < ApplicationRecord
  searchkick text_middle: [:name, :item_volume]
end

Моя текущая идея -

  1. открыть консоль рельсов в целевой среде
  2. обновить параметры поиска в моем классе Product, как указано выше
  3. создать новый индекс с Product.reindex(async: true)
  4. продвигать новый индекс после развертывания моего приложения с Product.search_index.promote(index_name).

К сожалению, при этом searchkick не позволяет мне изменить параметры и повышает:

RuntimeError (только один раз вызывать searchkick для каждой модели)

Есть идеи?


Traceback (most recent call last):
       10: from bin/rails:9:in `<main>'
        9: from bin/rails:9:in `require'
        8: from /app/vendor/bundle/ruby/2.5.0/gems/railties-4.2.11/lib/rails/commands.rb:17:in `<top (required)>'
        7: from /app/vendor/bundle/ruby/2.5.0/gems/railties-4.2.11/lib/rails/commands/commands_tasks.rb:39:in `run_command!'
        6: from /app/vendor/bundle/ruby/2.5.0/gems/railties-4.2.11/lib/rails/commands/commands_tasks.rb:68:in `console'
        5: from /app/vendor/bundle/ruby/2.5.0/gems/railties-4.2.11/lib/rails/commands/console.rb:9:in `start'
        4: from /app/vendor/bundle/ruby/2.5.0/gems/railties-4.2.11/lib/rails/commands/console.rb:110:in `start'
        3: from (irb):1
        2: from (irb):8:in `<class:Product>'
        1: from /app/vendor/bundle/ruby/2.5.0/gems/searchkick-2.5.0/lib/searchkick/model.rb:11:in `searchkick'

1 Ответ

2 голосов
/ 06 мая 2019

Я бы предложил сделать это на рабочем месте, и вы можете использовать, возможно, переменную модели Config или Redis cahce, чтобы настроить вашу модель на готовность использовать новый индекс после его продвижения.

class UpdateProductIndexWorker
  include Sidekiq::Worker
  sidekiq_options retry: 0

  def peform
    #patch your product model for this job
    class Product
      searchkick text_middle: [:name, :item_volume]
    end
    # track status of reindex
    Searchkick.redis = Redis.new 
    new_index = Product.reindex(async: true)
    index_name = new_index['index_name']  
    loop do
      break if Searchkick.reindex_status(index_name)[:completed]
      sleep 60 # or however long you want to interval check
    end
    # You'll need to tell your app somehow to use new index
    # You could use perhaps a Config model which could be something
    # you could store in the database for exmaple:
    # Config.create(name: 'use_new_products_index', state: true)
    # or use redis assuming it's your Rails cache
    Rails.cache.write('use_new_product_index', true, expires_in: 1.year)  
    # now you can just use the new index
    Product.searchkick_index.promote(index_name)
  end
end

Обновите вашу модель, чтобы использовать новый индекс, когда она будет готова.

class Product < ApplicationRecord

  def self.use_new_index?
    # Config.find_by(name: 'use_new_products_index').try(:state)
    # or use Rails/redis cachea
    Rails.cache.read('use_new_product_index')
  end
  # use the config data to make the model backward compatable until
  # the new index is ready.  Later you'll remove this in a cleanup deploy.
  if Product.use_new_index?
    searchkick text_middle: [:name, :item_volume]
  else
    searchkick
  end
end
...