Class: FullSearch::Search

Inherits:
Object
  • Object
show all
Includes:
Quoting
Defined in:
lib/full_search/search.rb

Constant Summary collapse

MIN_TERM_LENGTH =
3

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(model, query, filters:, include_soft_deleted:, limit:, offset:, highlight: false, highlight_fields: false, matching_strategy: nil, per_strategy_limit: nil) ⇒ Search

Returns a new instance of Search.



7
8
9
10
11
12
13
14
15
16
17
18
# File 'lib/full_search/search.rb', line 7

def initialize(model, query, filters:, include_soft_deleted:, limit:, offset:, highlight: false, highlight_fields: false, matching_strategy: nil, per_strategy_limit: nil)
  @model = model
  @query = query.to_s.strip
  @filters = filters
  @include_soft_deleted = include_soft_deleted
  @limit = limit
  @offset = offset
  @highlight = highlight
  @highlight_fields = highlight_fields
  @matching_strategy = matching_strategy
  @per_strategy_limit = per_strategy_limit
end

Instance Attribute Details

#filtersObject (readonly)

Returns the value of attribute filters.



5
6
7
# File 'lib/full_search/search.rb', line 5

def filters
  @filters
end

#highlightObject (readonly)

Returns the value of attribute highlight.



5
6
7
# File 'lib/full_search/search.rb', line 5

def highlight
  @highlight
end

#highlight_fieldsObject (readonly)

Returns the value of attribute highlight_fields.



5
6
7
# File 'lib/full_search/search.rb', line 5

def highlight_fields
  @highlight_fields
end

#include_soft_deletedObject (readonly)

Returns the value of attribute include_soft_deleted.



5
6
7
# File 'lib/full_search/search.rb', line 5

def include_soft_deleted
  @include_soft_deleted
end

#limitObject (readonly)

Returns the value of attribute limit.



5
6
7
# File 'lib/full_search/search.rb', line 5

def limit
  @limit
end

#matching_strategyObject (readonly)

Returns the value of attribute matching_strategy.



5
6
7
# File 'lib/full_search/search.rb', line 5

def matching_strategy
  @matching_strategy
end

#modelObject (readonly)

Returns the value of attribute model.



5
6
7
# File 'lib/full_search/search.rb', line 5

def model
  @model
end

#offsetObject (readonly)

Returns the value of attribute offset.



5
6
7
# File 'lib/full_search/search.rb', line 5

def offset
  @offset
end

#per_strategy_limitObject (readonly)

Returns the value of attribute per_strategy_limit.



5
6
7
# File 'lib/full_search/search.rb', line 5

def per_strategy_limit
  @per_strategy_limit
end

#queryObject (readonly)

Returns the value of attribute query.



5
6
7
# File 'lib/full_search/search.rb', line 5

def query
  @query
end

Instance Method Details

#relationObject



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/full_search/search.rb', line 22

def relation
  validate_filter_keys!
  validate_required_filters!
  check_stale_config!

  return model.none if dsl.tokenize == "trigram" && query.length < MIN_TERM_LENGTH && !dsl.typo_tolerance?

  parsed = QueryParser.parse(query)
  exact_ids = ExactMatch.ids_for(model, query, filters)
  primary_ids = fts_match_ids(parsed)
  fallback_ids = (dsl.typo_tolerance? && matching_strategy != "all") ? trigram_match_ids(parsed, primary_ids, candidate_limit: per_strategy_limit) : []
  fuzzy_ids = (dsl.typo_tolerance? && matching_strategy != "all" && primary_ids.empty? && fallback_ids.empty?) ? fuzzy_match_ids(parsed, candidate_limit: per_strategy_limit) : []

  all_ids = (exact_ids + primary_ids + fallback_ids + fuzzy_ids).uniq
  return model.none if all_ids.empty?

  rel = model.where(id: all_ids)
  rel = rel.where(model.arel_table[dsl.soft_delete_column].eq(nil)) if dsl.soft_delete_column && !include_soft_deleted
  rel = rel.limit(limit) if limit
  rel = rel.offset(offset) if offset

  rel = apply_ranking(rel, all_ids, exact_ids)

  if highlight
    records = rel.to_a
    Highlighter.apply!(records, model, query, record_ids: records.map(&:id))
    records
  elsif highlight_fields
    records = rel.to_a
    Highlighter.apply_fields!(records, model, query, record_ids: records.map(&:id))
    records
  else
    rel
  end
end