Ruby elasticsearch-model - configuring multiple mappings -


module spree     product.class_eval        include elasticsearch::model  index_name spree::elasticsearchsettings.index document_type 'spree_product'    mapping _all: {"index_analyzer" => "ngram_analyzer", "search_analyzer" => "whitespace_analyzer"}     indexes :name, type: 'multi_field'       indexes :name, type: 'string', analyzer:'ngram_analyzer', boost: 100       indexes :untouched, type: 'string', include_in_all: false, index: 'not_analyzed'     end      indexes :name_whole, type: 'multi_field'       indexes :name, type: 'string', index_analyzer:'simple'     end      indexes :name_completion, type: 'multi_field'       indexes :untouched, type: 'string', include_in_all: false, index: 'not_analyzed'     end      indexes :taxon_ids, type: 'multi_field'       indexes :taxon_ids, type:'string', analyzer: 'simple'       indexes :taxon_ids_ngram, type:'string', analyzer:'ngram_analyzer'     end     indexes :description, analyzer: 'snowball', include_in_all:false     indexes :available_on, type: 'date', format: 'dateoptionaltime', include_in_all: false     indexes :price, type: 'double', include_in_all:false     indexes :sku, type: 'string', index: 'not_analyzed', include_in_all:false     indexes :properties, type: 'string', index: 'not_analyzed', include_in_all:false  end   mapping _suggest: {"index_analyzer" => "simple", "search_analyzer" => "whitespace_analyzer"}     indexes :name_completion, type: 'multi_field'       indexes :name, type: 'completion', index_analyzer:'simple', search_analyzer: 'simple', payloads: true     end       indexes :taxon_ids, type: 'multi_field'       indexes :taxon_ids, type:'string', analyzer: 'simple'       indexes :taxon_ids_ngram, type:'string', analyzer:'ngram_analyzer'     end     indexes :description, analyzer: 'snowball', include_in_all:false     indexes :available_on, type: 'date', format: 'dateoptionaltime', include_in_all: false     indexes :price, type: 'double', include_in_all:false     indexes :sku, type: 'string', index: 'not_analyzed', include_in_all:false     indexes :properties, type: 'string', index: 'not_analyzed', include_in_all:false  end  def as_indexed_json(options={})   result = as_json({     methods: [:price, :sku],     only: [:available_on, :description, :name],     include: {       variants: {         only: [:sku],         include: {           option_values: {             only: [:name, :presentation]           }         }       }     }   })   result[:properties] = property_list unless property_list.empty?   result[:taxon_ids] = taxons.map(&:self_and_ancestors).flatten.uniq.map(&:id) unless taxons.empty?   result end  # inner class used query elasticsearch. idea query dynamically build based on parameters. class product::elasticsearchquery   include ::virtus.model    attribute :from, integer, default: 0   attribute :price_min, float   attribute :price_max, float   attribute :properties, hash   attribute :query, string   attribute :taxons, array   attribute :browse_mode, boolean   attribute :sorting, string    # when browse_mode enabled, taxon filter placed @ top level. causes results limited, facetting done on complete dataset.   # when browse_mode disabled, taxon filter placed inside filtered query. causes facets limited resulting set.    # method creates actual query based on current attributes.   # idea use following schema , fill in blanks.   # {   #   query: {   #     filtered: {   #       query: {   #         query_string: { query: , fields: [] }   #       }   #       filter: {   #         and: [   #           { terms: { taxons: [] } },   #           { terms: { properties: [] } }   #         ]   #       }   #     }   #   }   #   filter: { range: { price: { lte: , gte: } } },   #   sort: [],   #   from: ,   #   facets:   # }   def to_hash     q = { match_all: {} }     unless query.blank? # nil or empty       q = { query_string: { query: query, fields: ['name^5','description','sku'], default_operator: 'and', use_dis_max: true } }     end     query = q      and_filter = []     unless @properties.nil? || @properties.empty?       # transform properties [{"key1" => ["value_a","value_b"]},{"key2" => ["value_a"]}       # { terms: { properties: ["key1||value_a","key1||value_b"] }       #    { terms: { properties: ["key2||value_a"] }       # enforces "and" relation between different property values , "or" relation between same property values       properties = @properties.map {|k,v| [k].product(v)}.map |pair|         and_filter << { terms: { properties: pair.map {|prop| prop.join("||")} } }       end     end      sorting = case @sorting     when "name_asc"       [ {"name.untouched" => { order: "asc" }}, {"price" => { order: "asc" }}, "_score" ]     when "name_desc"       [ {"name.untouched" => { order: "desc" }}, {"price" => { order: "asc" }}, "_score" ]     when "price_asc"       [ {"price" => { order: "asc" }}, {"name.untouched" => { order: "asc" }}, "_score" ]     when "price_desc"       [ {"price" => { order: "desc" }}, {"name.untouched" => { order: "asc" }}, "_score" ]     when "score"       [ "_score", {"name.untouched" => { order: "asc" }}, {"price" => { order: "asc" }} ]     else       [ {"name.untouched" => { order: "asc" }}, {"price" => { order: "asc" }}, "_score" ]     end      # facets     facets = {       price: { statistical: { field: "price" } },       properties: { terms: { field: "properties", order: "count", size: 1000000 } },       taxon_ids: { terms: { field: "taxon_ids", size: 1000000 } }     }      # basic skeleton     result = {       min_score: 0.1,       query: { filtered: {} },       sort: sorting,       from: from,       facets: facets     }      # add query , filters filtered     result[:query][:filtered][:query] = query     # taxon , property filters have effect on facets     and_filter << { terms: { taxon_ids: taxons } } unless taxons.empty?     # return products available     #and_filter << { range: { available_on: { lte: "now" } } }     result[:query][:filtered][:filter] = { "and" => and_filter } unless and_filter.empty?      # add price filter outside query because should have no effect on facets     if price_min && price_max && (price_min < price_max)       result[:filter] = { range: { price: { gte: price_min, lte: price_max } } }     end     result   end end  private  def property_list   product_properties.map{|pp| "#{pp.property.name}||#{pp.value}"} end end end 

i have following model 2 mappings, 1 conventional search other search suggestions. latter mapping required according elasticsearch docs enable completion suggestor - https://www.elastic.co/guide/en/elasticsearch/reference/current/search-suggesters-completion.html.

when indexing above model following error: [400] {"error":"mapperparsingexception[mapping [spree_product]]; nested: mapperparsingexception[root type mapping not empty after parsing! remaining fields: [_suggest : {search_analyzer=whitespace_analyzer, index_analyzer=simple}]]; ","status":400} /usr/local/bundle/gems/elasticsearch-transport-1.0.12/lib/elasticsearch/transport/transport/base.rb:135:in __raise_transport_error' /usr/local/bundle/gems/elasticsearch-transport-1.0.12/lib/elasticsearch/transport/transport/base.rb:227:inperform_request' /usr/local/bundle/gems/elasticsearch-transport-1.0.12/lib/elasticsearch/transport/transport/http/faraday.rb:20:in perform_request' /usr/local/bundle/gems/elasticsearch-transport-1.0.12/lib/elasticsearch/transport/client.rb:119:inperform_request' /usr/local/bundle/gems/elasticsearch-api-1.0.12/lib/elasticsearch/api/namespace/common.rb:21:in perform_request' /usr/local/bundle/gems/elasticsearch-api-1.0.12/lib/elasticsearch/api/actions/indices/create.rb:77:increate' /tmp/spree_elasticsearch/lib/tasks/load_products.rake:5:in `block (2 levels) in ' tasks: top => spree_elasticsearch:load_products

found issue. not idea nest field completion

set mapping: mapping indexes :name_completion, type: 'completion', payloads: true end

ensure correct json returned indexing:

[:name_completion] = { input: name, output: name, payload: "" }

referenced example: https://github.com/elastic/elasticsearch-rails/commit/ded20356920802c35d258756113acfd95b25ade6


Comments

Popular posts from this blog

twig - Using Twigbridge in a Laravel 5.1 Package -

Kivy: Swiping (Carousel & ScreenManager) -

jdbc - Not able to establish database connection in eclipse -