Module: Polysearch::Searchable

Extended by:
ActiveSupport::Concern
Defined in:
app/models/polysearch/searchable.rb

Defined Under Namespace

Modules: ClassMethods

Instance Method Summary collapse

Instance Method Details

#similarity_ngramsObject



102
103
104
105
106
# File 'app/models/polysearch/searchable.rb', line 102

def similarity_ngrams
  similarity_words.each_with_object(Set.new) do |word, memo|
    ngrams(word).each { |ngram| memo << ngram }
  end.to_a.sort_by(&:length)
end

#similarity_wordsObject



88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'app/models/polysearch/searchable.rb', line 88

def similarity_words
  tsvectors = to_tsvectors.compact.uniq
  return [] if tsvectors.blank?
  tsvector = tsvectors.join(" || ")

  ts_stat = Arel::Nodes::NamedFunction.new("ts_stat", [
    Arel::Nodes::SqlLiteral.new(sanitize_sql_value("SELECT #{tsvector}"))
  ])
  length = Arel::Nodes::NamedFunction.new("length", [Arel::Nodes::SqlLiteral.new(quote_column_name(:word))])
  query = self.class.select(:word).from(ts_stat.to_sql).where(length.gteq(3)).to_sql
  result = self.class.connection.execute(query)
  result.values.flatten
end

#similarity_words_tsvectors(weight: "D") ⇒ Object



108
109
110
111
112
# File 'app/models/polysearch/searchable.rb', line 108

def similarity_words_tsvectors(weight: "D")
  similarity_ngrams.each_with_object([]) do |ngram, memo|
    memo << make_tsvector(ngram, weight: weight)
  end
end

#to_tsvectorsObject

Polysearch::Searchable#to_tsvectors is abstract… a noop by default it must be implemented in including ActiveRecord models if this behavior is desired

Example:

def to_tsvectors

[]
  .then { |result| result << make_tsvector(EXAMPLE_COLUMN_OR_PROPERTY, weight: "A") }
  .then { |result| EXAMPLE_TAGS_COLUMN.each_with_object(result) { |tag, memo| memo << make_tsvector(tag, weight: "B") } }

end



84
85
86
# File 'app/models/polysearch/searchable.rb', line 84

def to_tsvectors
  []
end

#update_polysearchObject



62
63
64
65
66
67
68
69
70
71
# File 'app/models/polysearch/searchable.rb', line 62

def update_polysearch
  tsvectors = to_tsvectors.compact.uniq
  return if tsvectors.blank?
  tsvectors.pop while tsvectors.size > 500
  tsvectors.concat similarity_words_tsvectors
  tsvector = tsvectors.join(" || ")
  fts = Polysearch::Record.where(searchable: self).first_or_create
  fts.update_value tsvector
  fts.update_columns words: similarity_words.join(" ")
end