Created
May 26, 2016 04:39
-
-
Save webgago/96da7a263c5b27c43a7be7101b93561f to your computer and use it in GitHub Desktop.
chewy example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/search/base_search.rb | |
class BaseSearch | |
class_attribute :index | |
class_attribute :per_page | |
self.per_page = 20 | |
def initialize(params={}, &block) | |
@index = self.index.constantize | |
@params = params.dup | |
@q = params[:query].presence | |
yield self if block_given? | |
end | |
def search(&block) | |
rescue_search do | |
@query ||= if block_given? | |
paginate yield(query) | |
else | |
paginate query | |
end | |
end | |
end | |
def query | |
raise NotImplementedError | |
end | |
def result_from | |
offset + 1 | |
end | |
def result_to | |
offset + @query.count | |
end | |
def offset | |
(page - 1) * per_page | |
end | |
def page | |
(@params[:page].presence || 1).to_i | |
end | |
def total_count | |
@query.total_count | |
end | |
private | |
def paginate(query) | |
query.offset(offset).limit(per_page) | |
end | |
def q | |
return {} unless @q.present? | |
{ | |
query_string: { | |
fields: searchable_attributes, | |
query: @q, | |
default_operator: 'and'} | |
} | |
end | |
def searchable_attributes | |
raise NotImplementedError | |
end | |
def by_term(name, value=@params[name]) | |
return {} unless value.present? | |
{ | |
term: { | |
name => value | |
} | |
} | |
end | |
def by_boolean(name, value=@params[name]) | |
{ | |
term: { | |
name => !!value | |
} | |
} | |
end | |
def by_terms(name, value=@params[name]) | |
return {} unless value.present? | |
{ | |
terms: { | |
name => value, | |
execution: 'bool' | |
} | |
} | |
end | |
def by_range(name, to: @params[:"#{name}_to"], from: @params[:"#{name}_from"]) | |
range = {} | |
return range unless to.present? || from.present? | |
range[:gte] = from.to_f if from.present? | |
range[:lte] = to.to_f if to.present? | |
{ | |
range: { | |
name => range | |
} | |
} | |
end | |
def by_range_dates(name, to: @params[:"#{name}_from"], from: @params[:"#{name}_to"]) | |
range = {} | |
return range unless to.present? || from.present? | |
range[:gte] = from if from.present? | |
range[:lte] = to if to.present? | |
{ | |
range: { | |
name => range | |
} | |
} | |
end | |
def rescue_search &block | |
block.call.tap { |scope| scope.to_a } | |
rescue Elasticsearch::Transport::Transport::Errors::BadRequest => e | |
@error = e.message.match(/QueryParsingException\[([^;]+)\]/).try(:[], 1) | |
Rails.logger.error(e) | |
@index.none | |
end | |
end | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/chewy/concerns/index_analizers.rb | |
module Concerns | |
module IndexAnalizers | |
def self.included(base) | |
base.class_eval do | |
settings analysis: { | |
analyzer: { | |
name: { | |
tokenizer: 'standard', | |
filter: ['lowercase'] | |
}, | |
sorted: { | |
tokenizer: 'keyword', | |
filter: ['lowercase'] | |
}, | |
prase: { | |
tokenizer: 'keyword', | |
filter: ['lowercase'] | |
} | |
} | |
} | |
end | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/chewy/properties_index.rb | |
class PropertysIndex < Chewy::Index | |
include Concerns::IndexAnalizers | |
define_type Property do | |
field :type, index: 'not_analyzed' | |
field :title, analyzer: 'name' | |
field :manager, analyzer: 'name', value: -> { manager.try(:full_title) } | |
field :manager_id, index: 'not_analyzed' # to be able filter out by manager for example | |
field :company, analyzer: 'name', value: -> { company.name } | |
field :company_id, index: 'not_analyzed' | |
field :address, analyzer: 'name', value: -> { full_address } | |
field :created_at, type: 'date', include_in_all: false | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/search/properties_search.rb | |
class PropertiesSearch < BaseSearch | |
self.index = 'PropertiesIndex' | |
def query | |
@index. | |
query(q). | |
filter(by_manager). | |
filter(by_company). | |
load(scope: scope) | |
end | |
def scope | |
Property.includes(:manager, :company) | |
end | |
private | |
def by_manager | |
by_term(:manager_id) | |
end | |
def by_company | |
by_term(:company_id) | |
end | |
def searchable_attributes | |
[ | |
:type, | |
:title, | |
:manager, | |
:company, | |
:address | |
] | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment