Создайте индекс с новыми параметрами searchkick в консоли rails

Я ищу способ легко обновить свой индекс Elasticsearch.

Я перехожу из:

class Product < ApplicationRecord
  searchkick
end

To:

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

Моя текущая идея состоит в том, чтобы

  1. открыть консоль rails в целевой среде
  2. обновить параметры поиска моего класса продукта, как указано выше
  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'

person RaphaMex    schedule 05.05.2019    source источник
comment
Не могли бы вы предоставить обратную связь   -  person The Wizard    schedule 06.05.2019
comment
у вас есть большой объем данных для renidex? Вы ожидаете, что это будет работать быстро или займет много времени?   -  person lacostenycoder    schedule 06.05.2019
comment
@lacostenycoder: да, он довольно большой, это может занять 8 часов   -  person RaphaMex    schedule 06.05.2019


Ответы (1)


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

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
person lacostenycoder    schedule 06.05.2019
comment
@RaphaMex при работе над любым видом модификации данных всегда полезно подходить к проблеме таким образом, который поддерживает нулевое время простоя и требует наименьшего количества ручного процесса, если вообще требуется. Когда что-то займет много времени, работники — ваши друзья. Дайте мне знать, если это работает для вас. - person lacostenycoder; 06.05.2019