Method: Searchkick::IndexOptions#add_synonyms

Defined in:
lib/searchkick/index_options.rb

#add_synonyms(settings) ⇒ Object



464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
# File 'lib/searchkick/index_options.rb', line 464

def add_synonyms(settings)
  synonyms = options[:synonyms] || []
  synonyms = synonyms.call if synonyms.respond_to?(:call)
  if synonyms.any?
    settings[:analysis][:filter][:searchkick_synonym] = {
      type: "synonym",
      # only remove a single space from synonyms so three-word synonyms will fail noisily instead of silently
      synonyms: synonyms.select { |s| s.size > 1 }.map { |s| s.is_a?(Array) ? s.map { |s2| s2.sub(/\s+/, "") }.join(",") : s }.map(&:downcase)
    }
    # choosing a place for the synonym filter when stemming is not easy
    # https://groups.google.com/forum/#!topic/elasticsearch/p7qcQlgHdB8
    # TODO use a snowball stemmer on synonyms when creating the token filter

    # http://elasticsearch-users.115913.n3.nabble.com/synonym-multi-words-search-td4030811.html
    # I find the following approach effective if you are doing multi-word synonyms (synonym phrases):
    # - Only apply the synonym expansion at index time
    # - Don't have the synonym filter applied search
    # - Use directional synonyms where appropriate. You want to make sure that you're not injecting terms that are too general.
    settings[:analysis][:analyzer][default_analyzer][:filter].insert(2, "searchkick_synonym")

    %w(word_start word_middle word_end).each do |type|
      settings[:analysis][:analyzer]["searchkick_#{type}_index".to_sym][:filter].insert(2, "searchkick_synonym")
    end
  end
end