class Mastico::Query
Constants
- DEFAULT_OPTIONS
- QUERY_TYPES
Attributes
fields[R]
options[R]
query[R]
word_weight[R]
Public Class Methods
new(query:, fields:, word_weight: ->(_w) { 1.0 }
click to toggle source
# File lib/mastico/query.rb, line 22 def initialize(query:, fields:, word_weight: ->(_w) { 1.0 }, options: DEFAULT_OPTIONS) @query = query @fields = fields @word_weight = word_weight @options = options @parts = nil end
Public Instance Methods
apply(scope)
click to toggle source
# File lib/mastico/query.rb, line 30 def apply(scope) parts ? scope.query(parts) : scope end
Private Instance Methods
chewy_multi_match_fuzzy_query(query:, fields:, boost: nil)
click to toggle source
# File lib/mastico/query.rb, line 154 def chewy_multi_match_fuzzy_query(query:, fields:, boost: nil) return nil if fields.empty? lower = query.downcase chewy_multi_match_query( type: :fuzzy, query: lower, fields: fields, options: {boost: boost, fuzziness: options[:fuzziness]} ) end
chewy_multi_match_infix_query(query:, fields:, boost: nil)
click to toggle source
# File lib/mastico/query.rb, line 144 def chewy_multi_match_infix_query(query:, fields:, boost: nil) return nil if fields.empty? lower = query.downcase wildcard = "*#{lower}*" chewy_multi_match_query( type: :wildcard, query: wildcard, fields: fields, options: {boost: boost} ) end
chewy_multi_match_prefix_query(query:, fields:, boost: nil)
click to toggle source
# File lib/mastico/query.rb, line 135 def chewy_multi_match_prefix_query(query:, fields:, boost: nil) return nil if fields.empty? lower = query.downcase chewy_multi_match_query( type: :prefix, query: lower, fields: fields, options: {boost: boost} ) end
chewy_multi_match_query(type:, query:, fields:, options: {})
click to toggle source
# File lib/mastico/query.rb, line 164 def chewy_multi_match_query(type:, query:, fields:, options: {}) opts = options.dup boost = opts.delete(:boost) should = fields.map do |f| match = {value: query}.merge(opts) match[:boost] = boost if boost field = {type => {f => match}} field end {bool: {should: should, minimum_should_match: 0}} # OR over fields end
chewy_multi_match_word_query(query:, fields:, boost: nil)
click to toggle source
# File lib/mastico/query.rb, line 126 def chewy_multi_match_word_query(query:, fields:, boost: nil) return nil if fields.empty? lower = query.downcase chewy_multi_match_query( type: :term, query: lower, fields: fields, options: {boost: boost} ) end
chewy_term_query(word:, weight:)
click to toggle source
# File lib/mastico/query.rb, line 60 def chewy_term_query(word:, weight:) parts = [] if word.length >= options[:minimum_word_length] relevant_fields(:word).each do |field, field_boost| parts << chewy_multi_match_word_query( query: word, fields: [field], boost: options[:word_boost] * weight * field_boost ) end end if word.length >= options[:minimum_prefix_length] relevant_fields(:prefix).each do |field, field_boost| parts << chewy_multi_match_prefix_query( query: word, fields: [field], boost: options[:prefix_boost] * weight * field_boost ) end end if word.length >= options[:minimum_infix_length] relevant_fields(:infix).each do |field, field_boost| parts << chewy_multi_match_infix_query( query: word, fields: [field], boost: options[:infix_boost] * weight * field_boost ) end end if word.length >= options[:minimum_fuzzy_length] relevant_fields(:fuzzy).each do |field, field_boost| parts << chewy_multi_match_fuzzy_query( query: word, fields: [field], boost: options[:fuzzy_boost] * weight * field_boost ) end end parts.compact! if parts.size > 0 {bool: {should: parts}} # OR end end
parts()
click to toggle source
# File lib/mastico/query.rb, line 36 def parts @parts ||= begin clean = query.strip.gsub(/\s+/, ' ').downcase words = clean.split(" ") word_subqueries = words.map do |word| weight = word_weight.call(word) next nil if weight == 0.0 chewy_term_query(word: word, weight: weight) end word_subqueries = word_subqueries.compact case word_subqueries.size when 0 nil when 1 word_subqueries[0] else # We have multiple words in the query - # all of them **must** match {bool: {must: word_subqueries}} # AND query end end end
relevant_fields(search_type)
click to toggle source
# File lib/mastico/query.rb, line 110 def relevant_fields(search_type) if fields.is_a? Array fields.map { |field| [field, 1] }.to_h else fields.select do |field, options| if options[:types] options[:types].include?(search_type) else true end end.map do |field, options| [field, options.fetch(:boost, 1)] end.to_h end end