Class: FullSearch::Search

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

Constant Summary collapse

MIN_TERM_LENGTH =
FullSearch::Constants::MIN_TERM_LENGTH

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, scope: nil, includes: nil) ⇒ Search

Returns a new instance of Search.



7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 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, scope: nil, includes: 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
  @scope = scope
  @includes = includes
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

#includesObject (readonly)

Returns the value of attribute includes.



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

def includes
  @includes
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

#scopeObject (readonly)

Returns the value of attribute scope.



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

def scope
  @scope
end

Instance Method Details

#relationObject



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
57
58
59
60
61
# File 'lib/full_search/search.rb', line 24

def relation
  FullSearch::Instrumentation.instrument("query", model: model.name, query: query) do
    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 = apply_ranking(rel, all_ids, exact_ids)
    rel = scope.call(rel) if scope
    rel = rel.limit(limit) if limit
    rel = rel.offset(offset) if offset
    rel = rel.includes(includes) if includes

    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
end