module Runestone
Constants
- DEFAULT_APPROXIMATIONS
- VERSION
Public Class Methods
add_synonym(word, *replacements)
click to toggle source
# File lib/runestone.rb, line 74 def self.add_synonym(word, *replacements) word = normalize(word) replacements.map! { |r| normalize(r) } word = word.split(/\s+/) last = word.pop syn = synonyms word.each do |w| syn = if syn.has_key?(w) && h = syn[w].find { |i| i.is_a?(Hash) } h else h = {} syn[w] ||= [] syn[w] << h h end end syn[last] ||= [] syn[last] += replacements syn[last].uniq! end
add_synonyms(dictionary)
click to toggle source
# File lib/runestone.rb, line 68 def self.add_synonyms(dictionary) dictionary.each do |k, v| add_synonym(k, *v) end end
normalize(string)
click to toggle source
# File lib/runestone.rb, line 50 def self.normalize(string) string = string.downcase string = string.unicode_normalize! string rescue Encoding::CompatibilityError string end
normalize!(string)
click to toggle source
# File lib/runestone.rb, line 58 def self.normalize!(string) string.downcase! string.unicode_normalize! rescue Encoding::CompatibilityError end
Public Instance Methods
search(query, dictionary: nil, prefix: :last, normalization: nil)
click to toggle source
# File lib/runestone.rb, line 98 def search(query, dictionary: nil, prefix: :last, normalization: nil) exact_search = Runestone::WebSearch.parse(query, prefix: prefix) typo_search = exact_search.typos syn_search = typo_search.synonymize tsqueries = [exact_search, typo_search, syn_search].map(&:to_s).uniq.map do |q| ts_query(q, dictionary: dictionary) end q = if select_values.empty? select( klass.arel_table[Arel.star], *tsqueries.each_with_index.map { |q, i| Arel::Nodes::As.new(ts_rank_cd(:vector, q, dictionary: dictionary, normalization: normalization), Arel::Nodes::SqlLiteral.new("rank#{i}")) } ) else select( *tsqueries.each_with_index.map { |q, i| Arel::Nodes::As.new(ts_rank_cd(:vector, q, dictionary: dictionary, normalization: normalization), Arel::Nodes::SqlLiteral.new("rank#{i}")) } ) end q = if klass == Runestone::Model q.where(ts_match(:vector, tsqueries.last, dictionary: dictionary)) else q.joins(:runestones).where(ts_match(TS::Model.arel_table['vector'], tsqueries.last, dictionary: dictionary)) end q = q.where(dictionary: dictionary) if dictionary q.order( *tsqueries.each_with_index.map { |q, i| Arel::Nodes::Descending.new(Arel::Nodes::SqlLiteral.new("rank#{i}")) } ) end
transliterate(string)
click to toggle source
# File lib/runestone.rb, line 64 def transliterate(string) string.gsub(/[^\x00-\x7f]/u) { |char| approximations[char] || char } end