Class: IndexedSearch::Match::DoubleMetaphone
- Defined in:
- lib/indexed_search/match/double_metaphone.rb
Overview
Does a double metaphone algorithm comparison to find words that sound similar. This only works well for English.
You know, they claim this is newer and “better” than the old regular Metaphone, but the keys are way shorter and match tons more words (that aren’t even as similar, kind of like soundex), so rank this just above soundex.
Uses primary_metaphone and secondary_metaphone columns to store values with each entry in the IndexedSearch::Word model.
Class Method Summary collapse
Instance Method Summary collapse
Methods inherited from Base
#find, find_attributes, #initialize, match_against_term?, #term_matches, #term_non_matches
Constructor Details
This class inherits a constructor from IndexedSearch::Match::Base
Class Method Details
.make_index_value(term) ⇒ Object
63 64 65 |
# File 'lib/indexed_search/match/double_metaphone.rb', line 63 def self.make_index_value(term) Text::Metaphone.(term).collect { |m| m.blank? ? nil : m[0..max_length] } end |
Instance Method Details
#results(do_all = false) ⇒ Object
67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/indexed_search/match/double_metaphone.rb', line 67 def results(do_all=false) [].tap do |res| if do_all || term_maps[1].present? res << IndexedSearch::Match::Result.new(self, term_maps[1], rank_multiplier[0], term_multiplier[0], limit_reduction_factor, type_reduction_factor, 0) res << IndexedSearch::Match::Result.new(self, term_maps[1], rank_multiplier[1], term_multiplier[1], limit_reduction_factor, type_reduction_factor, 1) end if do_all || term_maps[2].present? res << IndexedSearch::Match::Result.new(self, term_maps[2], rank_multiplier[2], term_multiplier[2], limit_reduction_factor, type_reduction_factor, 0) res << IndexedSearch::Match::Result.new(self, term_maps[2], rank_multiplier[3], term_multiplier[3], limit_reduction_factor, type_reduction_factor, 1) end end end |
#scope ⇒ Object
37 38 39 40 |
# File 'lib/indexed_search/match/double_metaphone.rb', line 37 def scope @scope.where(@scope.arel_table[self.class.matcher_attribute.first].in(term_map.keys).or( @scope.arel_table[self.class.matcher_attribute.last].in(term_map.keys))) end |
#term_map ⇒ Object
42 43 44 |
# File 'lib/indexed_search/match/double_metaphone.rb', line 42 def term_map term_maps[0] end |
#term_maps ⇒ Object
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/indexed_search/match/double_metaphone.rb', line 45 def term_maps @term_maps ||= [].tap do |maps| # 3 maps: both, primary-only, secondary-only 3.times { maps << Hash.new { |hash,key| hash[key] = [] } } term_matches.each do |term| vals = self.class.make_index_value(term) unless vals.first.nil? maps[0][vals.first] << term maps[1][vals.first] << term end unless vals.last.nil? maps[0][vals.last] << term maps[2][vals.last] << term end end end end |