lib/searchkick/query.rb in searchkick_bharthur-0.0.1 vs lib/searchkick/query.rb in searchkick_bharthur-0.0.2

- old
+ new

@@ -45,17 +45,17 @@ klass ? klass.searchkick_klass : nil end def params index = - if options[:index_name] - Array(options[:index_name]).map { |v| v.respond_to?(:searchkick_index) ? v.searchkick_index.name : v }.join(",") - elsif searchkick_index - searchkick_index.name - else - "_all" - end + if options[:index_name] + Array(options[:index_name]).map { |v| v.respond_to?(:searchkick_index) ? v.searchkick_index.name : v }.join(",") + elsif searchkick_index + searchkick_index.name + else + "_all" + end params = { index: index, body: body } @@ -120,15 +120,15 @@ def handle_error(e) status_code = e.message[1..3].to_i if status_code == 404 raise MissingIndexError, "Index missing - run #{reindex_command}" elsif status_code == 500 && ( - e.message.include?("IllegalArgumentException[minimumSimilarity >= 1]") || - e.message.include?("No query registered for [multi_match]") || - e.message.include?("[match] query does not support [cutoff_frequency]]") || - e.message.include?("No query registered for [function_score]]") - ) + e.message.include?("IllegalArgumentException[minimumSimilarity >= 1]") || + e.message.include?("No query registered for [multi_match]") || + e.message.include?("[match] query does not support [cutoff_frequency]]") || + e.message.include?("No query registered for [function_score]]") + ) raise UnsupportedVersionError, "This version of Searchkick requires Elasticsearch 1.0 or greater" elsif status_code == 400 if e.message.include?("[multi_match] analyzer [searchkick_search] not found") raise InvalidQueryError, "Bad mapping - run #{reindex_command}" @@ -198,33 +198,33 @@ } else queries = [] misspellings = - if options.key?(:misspellings) - options[:misspellings] - elsif options.key?(:mispellings) - options[:mispellings] # why not? - else - true - end + if options.key?(:misspellings) + options[:misspellings] + elsif options.key?(:mispellings) + options[:mispellings] # why not? + else + true + end if misspellings.is_a?(Hash) && misspellings[:below] && !@misspellings_below @misspellings_below = misspellings[:below].to_i misspellings = false end if misspellings != false edit_distance = (misspellings.is_a?(Hash) && (misspellings[:edit_distance] || misspellings[:distance])) || 1 transpositions = - if misspellings.is_a?(Hash) && misspellings.key?(:transpositions) - {fuzzy_transpositions: misspellings[:transpositions]} - elsif below14? - {} - else - {fuzzy_transpositions: true} - end + if misspellings.is_a?(Hash) && misspellings.key?(:transpositions) + {fuzzy_transpositions: misspellings[:transpositions]} + elsif below14? + {} + else + {fuzzy_transpositions: true} + end prefix_length = (misspellings.is_a?(Hash) && misspellings[:prefix_length]) || 0 default_max_expansions = @misspellings_below ? 20 : 3 max_expansions = (misspellings.is_a?(Hash) && misspellings[:max_expansions]) || default_max_expansions end @@ -236,16 +236,16 @@ query: term, boost: 10 * factor } match_type = - if field.end_with?(".phrase") - field = field.sub(/\.phrase\z/, ".analyzed") - :match_phrase - else - :match - end + if field.end_with?(".phrase") + field = field.sub(/\.phrase\z/, ".analyzed") + :match_phrase + else + :match + end shared_options[:operator] = operator if match_type == :match || below50? if field == "_all" || field.end_with?(".analyzed") shared_options[:cutoff_frequency] = 0.001 unless operator == "and" || misspellings == false @@ -276,15 +276,15 @@ end if conversions_field && options[:conversions] != false # wrap payload in a bool query script_score = - if below12? - {script_score: {script: "doc['count'].value"}} - else - {field_value_factor: {field: "#{conversions_field}.count"}} - end + if below12? + {script_score: {script: "doc['count'].value"}} + else + {field_value_factor: {field: "#{conversions_field}.count"}} + end payload = { bool: { must: payload, should: { @@ -395,29 +395,29 @@ def set_fields boost_fields = {} fields = options[:fields] || searchkick_options[:searchable] fields = - if fields - if options[:autocomplete] - fields.map { |f| "#{f}.autocomplete" } - else - fields.map do |value| - k, v = value.is_a?(Hash) ? value.to_a.first : [value, options[:match] || searchkick_options[:match] || :word] - k2, boost = k.to_s.split("^", 2) - field = "#{k2}.#{v == :word ? 'analyzed' : v}" - boost_fields[field] = boost.to_f if boost - field - end - end + if fields + if options[:autocomplete] + fields.map { |f| "#{f}.autocomplete" } else - if options[:autocomplete] - (searchkick_options[:autocomplete] || []).map { |f| "#{f}.autocomplete" } - else - ["_all"] + fields.map do |value| + k, v = value.is_a?(Hash) ? value.to_a.first : [value, options[:match] || searchkick_options[:match] || :word] + k2, boost = k.to_s.split("^", 2) + field = "#{k2}.#{v == :word ? 'analyzed' : v}" + boost_fields[field] = boost.to_f if boost + field end end + else + if options[:autocomplete] + (searchkick_options[:autocomplete] || []).map { |f| "#{f}.autocomplete" } + else + ["_all"] + end + end [boost_fields, fields] end def set_boost_by_distance(custom_filters) boost_by_distance = options[:boost_by_distance] || {} @@ -523,11 +523,11 @@ def set_aggregations(payload) aggs = options[:aggs] payload[:aggs] = {} if aggs.is_a?(Hash) && aggs[:body] - payload[:aggs] = aggs[:body] + payload[:aggs] = aggs[:body] else aggs = Hash[aggs.map { |f| [f, {}] }] if aggs.is_a?(Array) # convert to more advanced syntax aggs.each do |field, agg_options| size = agg_options[:limit] ? agg_options[:limit] : 1_000 @@ -627,40 +627,51 @@ @facet_limits = facet_limits end def set_filters(payload, filters) - if options[:facets] || options[:aggs] - if below20? - payload[:filter] = { - and: filters - } - else - payload[:post_filter] = { - bool: { - filter: filters + if options[:custom] + payload[:query] = { + filtered: { + query: payload[:query], + filter: { + and: filters } } - end + } else - # more efficient query if no facets - if below20? - payload[:query] = { - filtered: { - query: payload[:query], - filter: { - and: filters + if options[:facets] || options[:aggs] + if below20? + payload[:filter] = { + and: filters + } + else + payload[:post_filter] = { + bool: { + filter: filters } } - } + end else - payload[:query] = { - bool: { - must: payload[:query], - filter: filters + # more efficient query if no facets + if below20? + payload[:query] = { + filtered: { + query: payload[:query], + filter: { + and: filters + } + } } - } + else + payload[:query] = { + bool: { + must: payload[:query], + filter: filters + } + } + end end end end # TODO id transformation for arrays @@ -726,22 +737,22 @@ end when :in filters << term_filters(field, op_value) else range_query = - case op - when :gt - {from: op_value, include_lower: false} - when :gte - {from: op_value, include_lower: true} - when :lt - {to: op_value, include_upper: false} - when :lte - {to: op_value, include_upper: true} - else - raise "Unknown where operator: #{op.inspect}" - end + case op + when :gt + {from: op_value, include_lower: false} + when :gte + {from: op_value, include_lower: true} + when :lt + {to: op_value, include_upper: false} + when :lte + {to: op_value, include_upper: true} + else + raise "Unknown where operator: #{op.inspect}" + end # issue 132 if (existing = filters.find { |f| f[:range] && f[:range][field] }) existing[:range][field].merge!(range_query) else filters << {range: {field => range_query}} @@ -799,15 +810,15 @@ def boost_filters(boost_by, options = {}) boost_by.map do |field, value| log = value.key?(:log) ? value[:log] : options[:log] value[:factor] ||= 1 script_score = - if below12? - script = log ? "log(doc['#{field}'].value + 2.718281828)" : "doc['#{field}'].value" - {script_score: {script: "#{value[:factor].to_f} * #{script}"}} - else - {field_value_factor: {field: field, factor: value[:factor].to_f, modifier: log ? "ln2p" : nil}} - end + if below12? + script = log ? "log(doc['#{field}'].value + 2.718281828)" : "doc['#{field}'].value" + {script_score: {script: "#{value[:factor].to_f} * #{script}"}} + else + {field_value_factor: {field: field, factor: value[:factor].to_f, modifier: log ? "ln2p" : nil}} + end { filter: { exists: { field: field