Skip to content

Instantly share code, notes, and snippets.

@valexl
Last active February 4, 2016 04:59
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 valexl/75b4e3939cc25df88aa4 to your computer and use it in GitHub Desktop.
Save valexl/75b4e3939cc25df88aa4 to your computer and use it in GitHub Desktop.
Example how to make search via Elasticsearch
# models/concerns/searchable.rb
module Searchable
extend ActiveSupport::Concern
included do
include Elasticsearch::Model
include Elasticsearch::Model::Callbacks
index_name [Rails.env, model_name.collection.gsub(/\//, '-')].join("_")
after_touch() { __elasticsearch__.index_document }
end
end
# models/model_name.rb
class ModelName < ActiveRecord::Base
include Searchable
# if you want you can change Elasticsearch index settings
settings do
mapping do
indexes :name, type: 'multi_field' do
indexes :name, boost: 10
indexes :sort, analyzer: 'sortable'# для сортировки
end
end
end
...
end
# lib/company/project/searcher/base_seacher.rb
class Company::Project::Searcher::BaseSeacher
#FIXME Name should be finished by ActiveRecord class name.
class << self
def get_query(query)
@get_query = { filtered: {
query: {}
}
}
query = query.to_s.strip
query = query.gsub(/\s+/, " ")
query = query.gsub(/-/, " ")
if query.length.zero?
@get_query[:filtered][:query][:match_all] = {}
else
@get_query[:filtered][:query][:multi_match] = {
query: query,
operator: 'AND',
fields: ["_all"]
}
end
@get_query
end
def get_sort(sort)
return {} if sort.blank?
field = sort.keys.first
direction = sort.values.first
{ field => { order: direction, missing: :_last }}
end
def get_paging(paging)
return { from: 0, size: 10 } if paging.blank?
paging.slice(:from, :size)
end
end
def initialize(query, options={})
@search_settings = {
query: Company::Project::Searcher::BaseSeacher.get_query(query),
sort: Company::Project::Searcher::BaseSeacher.get_sort(options[:sort]),
highlight: {
pre_tags: ['<em class="label label-highlight">'],
post_tags: ['</em>'],
fields: { "*" => { number_of_fragments: 0 } },
}
}
@search_settings.merge! Company::Project::Searcher::BaseSeacher.get_paging(options[:paging])
end
def get_records
records = klass.search(@search_settings, preference: '_primary').records
records
end
private
def klass
"::#{self.class.to_s.split("::").last}".constantize
end
end
# lib/company/project/searcher/model_name.rb
class Company::Project::Searcher::ModelName < Company::Project::Searcher::BaseSeacher
#FIXME Name should be finished by ActiveRecord class name.
#Also you can change behaviour for specific ActiveRecord model
end
#Search example:
Company::Project::Searcher::ModelName.new("Bla-bla-bla").get_records
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment