Skip to content

Instantly share code, notes, and snippets.

@nickrivadeneira
Created December 1, 2016 16:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nickrivadeneira/e99fbf9beb82fed2f95eaf6964c97853 to your computer and use it in GitHub Desktop.
Save nickrivadeneira/e99fbf9beb82fed2f95eaf6964c97853 to your computer and use it in GitHub Desktop.
Colocated Elasticsearch index manager
require "elasticsearch/rails/tasks/import"
namespace :elasticsearch do
namespace :import do
task combined: :environment do
if ENV["FORCE"]
SearchIndexManager.create_index(force: ENV["FORCE"])
end
SearchIndexManager.import
end
end
end
class SearchIndexManager
INDEX_NAME = "app_name_#{Rails.env}".freeze
INDEXED_MODELS = [FooModel, BarModel, BazModel].freeze
def self.create_index(options = {})
settings = INDEXED_MODELS.map(&:settings).reduce({}, &:merge)
mappings = INDEXED_MODELS.map(&:mappings).reduce({}, &:merge)
if options[:force]
delete_index
end
create index: INDEX_NAME, body: { settings: settings, mappings: mappings }
end
def self.delete_index
if exists? index: INDEX_NAME
delete index: INDEX_NAME
end
end
def self.refresh_index
if exists? index: INDEX_NAME
refresh index: INDEX_NAME
end
end
def self.import(options = {})
models_to_index = options[:models] || INDEXED_MODELS
if (models_to_index - INDEXED_MODELS).present?
raise TypeError, "The :models option cannot contain non-indexed models"
end
models_to_index.each do |model|
model.import batch_size: 1_000, scope: "for_importing"
end
end
class << self
private
delegate :create, :exists?, :delete, :refresh, to: :indices
def indices
Elasticsearch::Model.client.indices
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment