Module: Polysearch::Searchable
- Extended by:
- ActiveSupport::Concern
- Defined in:
- app/models/polysearch/searchable.rb
Defined Under Namespace
Modules: ClassMethods
Instance Method Summary collapse
- #similarity_ngrams ⇒ Object
- #similarity_words ⇒ Object
- #similarity_words_tsvectors(weight: "D") ⇒ Object
-
#to_tsvectors ⇒ Object
Polysearch::Searchable#to_tsvectors is abstract…
- #update_polysearch ⇒ Object
Instance Method Details
#similarity_ngrams ⇒ Object
118 119 120 121 122 |
# File 'app/models/polysearch/searchable.rb', line 118 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_words ⇒ Object
104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'app/models/polysearch/searchable.rb', line 104 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.unscoped.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
124 125 126 127 128 |
# File 'app/models/polysearch/searchable.rb', line 124 def similarity_words_tsvectors(weight: "D") similarity_ngrams.each_with_object([]) do |ngram, memo| memo << make_tsvector(ngram, weight: weight) end end |
#to_tsvectors ⇒ Object
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
100 101 102 |
# File 'app/models/polysearch/searchable.rb', line 100 def to_tsvectors [] end |
#update_polysearch ⇒ Object
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'app/models/polysearch/searchable.rb', line 62 def update_polysearch return unless persisted? tsvectors = to_tsvectors.compact.uniq return if tsvectors.blank? tsvectors.pop while tsvectors.size > 500 tsvectors.concat similarity_words_tsvectors tsvector = tsvectors.join(" || ") attributes = { searchable_type: self.class.name, searchable_id: id, words: similarity_words.join(" "), created_at: Time.current, updated_at: Time.current } result = Polysearch::Record.upsert( attributes, unique_by: [:searchable_type, :searchable_id], returning: :id ) record = Polysearch::Record.find_by(id: result.first["id"]) record.update_value tsvector end |