Skip to content

Instantly share code, notes, and snippets.

@phsacramento
Created February 16, 2017 01:37
Show Gist options
  • Save phsacramento/9227f91cf005cd7829b609032eda132e to your computer and use it in GitHub Desktop.
Save phsacramento/9227f91cf005cd7829b609032eda132e to your computer and use it in GitHub Desktop.
# encoding: UTF-8
module Searchable
extend ActiveSupport::Concern
included do
include Elasticsearch::Model
settings index_configuration do
mapping do
indexes :unit, {
type: :multi_field,
fields: {
unit: { type: 'string', analyzer: 'bmx_analyzer' },
unit_keyword: { type: 'string', analyzer: 'keyword' }
}
}
indexes :code, {
type: :multi_field,
fields: {
code: { type: 'string', analyzer: 'bmx_analyzer' },
code_gram: { type: 'string', index_analyzer: 'bmx_ngram_analyzer' },
code_keyword: { type: 'string', analyzer: 'keyword' },
code_delimiter: { type: 'string', analyzer: 'bmx_word_analyzer' }
}
}
indexes :slug, analyzer: 'keyword'
indexes :description, {
type: :multi_field,
fields: {
description: { type: 'string', analyzer: 'bmx_analyzer' },
description_gram: { type: 'string', index_analyzer: 'bmx_edge_ngram_analyzer' },
description_keyword: { type: 'string', index_analyzer: 'keyword' }
}
}
indexes :observation, analyzer: 'bmx_analyzer'
indexes :original_code, analyzer: 'bmx_analyzer'
indexes :secundary_code, analyzer: 'bmx_analyzer'
indexes :group_id, index: 'not_analyzed'
indexes :producer do
indexes :name, analyzer: 'bmx_analyzer'
indexes :slug, analyzer: 'keyword'
end
indexes :part_distributors do
indexes :city, analyzer: 'bmx_analyzer'
indexes :state, analyzer: 'bmx_analyzer'
indexes :price, analyzer: 'bmx_analyzer'
indexes :external_url, analyzer: 'bmx_analyzer'
indexes :name, index: 'not_analyzed', include_in_all: false
indexes :quantity, index: 'not_analyzed', include_in_all: false
indexes :email, index: 'not_analyzed', include_in_all: false
indexes :site, index: 'not_analyzed', include_in_all: false
indexes :phone, index: 'not_analyzed', include_in_all: false
indexes :address, index: 'not_analyzed', include_in_all: false
indexes :neighbourhood, index: 'not_analyzed', include_in_all: false
indexes :address_number, index: 'not_analyzed', include_in_all: false
indexes :address_complement, index: 'not_analyzed', include_in_all: false
indexes :zip_code, index: 'not_analyzed', include_in_all: false
end
indexes :related_parts_as_indexed_json do
indexes :code, index: 'not_analyzed', include_in_all: false
indexes :producer_name, index: 'not_analyzed', include_in_all: false
indexes :part_distributors_as_indexed_json do
indexes :name, index: 'not_analyzed', include_in_all: false
indexes :quantity, index: 'not_analyzed', include_in_all: false
indexes :price, index: 'not_analyzed', include_in_all: false
indexes :email, index: 'not_analyzed', include_in_all: false
indexes :site, index: 'not_analyzed', include_in_all: false
indexes :phone, index: 'not_analyzed', include_in_all: false
indexes :address, index: 'not_analyzed', include_in_all: false
indexes :neighbourhood, index: 'not_analyzed', include_in_all: false
indexes :address_number, index: 'not_analyzed', include_in_all: false
indexes :address_complement, index: 'not_analyzed', include_in_all: false
indexes :city, index: 'not_analyzed', include_in_all: false
indexes :state, index: 'not_analyzed', include_in_all: false
indexes :zip_code, index: 'not_analyzed', include_in_all: false
indexes :external_url, analyzer: 'bmx_analyzer'
end
end
indexes :applications, analyzer: 'bmx_analyzer'
end
end
index_name ENV['INDEX'] || "parts_#{Rails.env}"
document_type "part"
end
def as_indexed_json(options={})
as_json(
except: [
:id, :_id, :producer_id, :distributor_ids,
:created_at, :updated_at
],
include: {
producer: { only: [:name, :slug] },
part_distributors: {
only: [:name, :neighbourhood, :address, :address_number, :address_complement, :city, :phone, :email, :state, :zip_code, :price, :quantity, :site, :external_url],
methods: [:name, :neighbourhood, :address, :address_number, :address_complement, :city, :phone, :email, :state, :zip_code, :price, :quantity, :site, :external_url]
}
},
methods: [:related_parts_as_indexed_json, :applications, :group_id]
)
end
protected
def index_document
__elasticsearch__.index_document
end
def delete_document
__elasticsearch__.delete_document
end
module ClassMethods
def search_with_term(query=nil, options={})
query = query.try(:upcase)
group_id = options[:group_id]
sort = options[:sort]
code_multiplier = 3
@search_definition = {
sort: {},
query: {},
filter: {},
highlight: {
order: 'score',
fields: {
code: {},
description: {},
applications: { number_of_fragments: 15 },
'producer.name' => {}
}
}
}
if query.present?
@@query = query.gsub(/[\.\,\\\/\-*]/, "")
@@query2 = query.gsub(/[\(\)\[\]*]/, "")
@search_definition[:query] = {
dis_max: {
tie_breaker: 0.7,
boost: 1.2,
queries: [
{
multi_match: {
query: @@query,
type: 'cross_fields',
fields: [
"code",
"code_gram",
],
}
},
{
multi_match: {
query: @@query2,
type: 'cross_fields',
fields: [
"code",
"code_gram",
"description_gram^0.5",
"description^2",
"applications",
],
}
},
{
multi_match: {
query: @@query2,
type: 'most_fields',
fields: [
"code",
"description",
"applications",
],
#fuzziness: "auto"
}
},
{
match: {
"observation" => {
query: @@query,
boost: 0.1
},
}
},
{
match: {
"producer.name" => {
query: @@query,
boost: 1.4
},
}
},
]
}
}
#else
# @search_definition[:query] = { match_all: {} }
end
if group_id.present?
@search_definition[:filter] = {
not: {
term: {
group_id: group_id
}
}
}
end
if sort.present?
@search_definition[:sort] = [
{
configure_sort_field(sort) => {
order: 'asc'
}
}
]
end
__elasticsearch__.search(@search_definition)
end
def find_by_code(code_slug)
__elasticsearch__.search({ query: { match: { slug: code_slug } } }).results.first
end
def find_by_producer_and_code(producer_slug, code_slug)
__elasticsearch__.search({ filter: { and: [ { term: { slug: code_slug } },
{ term: { 'producer.slug' => producer_slug } } ] } }).results.first
end
protected
def index_configuration
@index_configuration ||= YAML.load_file(Rails.root.join('config', 'elasticsearch.yml'))
end
def configure_sort_field(field)
field.inquiry.producer? ? "#{field}.slug" : "#{field}_keyword"
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment