Class: Searchkick::Results

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
Enumerable
Defined in:
lib/searchkick/results.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(klass, response, options = {}) ⇒ Results

Returns a new instance of Results.



12
13
14
15
16
# File 'lib/searchkick/results.rb', line 12

def initialize(klass, response, options = {})
  @klass = klass
  @response = response
  @options = options
end

Instance Attribute Details

#klassObject (readonly)

Returns the value of attribute klass.



8
9
10
# File 'lib/searchkick/results.rb', line 8

def klass
  @klass
end

#optionsObject (readonly)

Returns the value of attribute options.



8
9
10
# File 'lib/searchkick/results.rb', line 8

def options
  @options
end

#responseObject (readonly)

Returns the value of attribute response.



8
9
10
# File 'lib/searchkick/results.rb', line 8

def response
  @response
end

Instance Method Details

#aggregationsObject



76
77
78
# File 'lib/searchkick/results.rb', line 76

def aggregations
  response["aggregations"]
end

#aggsObject



80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/searchkick/results.rb', line 80

def aggs
  @aggs ||= begin
    if aggregations
      aggregations.dup.each do |field, filtered_agg|
        buckets = filtered_agg[field]
        # move the buckets one level above into the field hash
        if buckets
          filtered_agg.delete(field)
          filtered_agg.merge!(buckets)
        end
      end
    end
  end
end

#current_pageObject



122
123
124
# File 'lib/searchkick/results.rb', line 122

def current_page
  options[:page]
end

#entry_name(options = {}) ⇒ Object



107
108
109
110
111
112
113
114
115
# File 'lib/searchkick/results.rb', line 107

def entry_name(options = {})
  if options.empty?
    # backward compatibility
    model_name.human.downcase
  else
    default = options[:count] == 1 ? model_name.human : model_name.human.pluralize
    model_name.human(options.reverse_merge(default: default))
  end
end

#errorObject



99
100
101
# File 'lib/searchkick/results.rb', line 99

def error
  response["error"]
end

#first_page?Boolean

Returns:

  • (Boolean)


154
155
156
# File 'lib/searchkick/results.rb', line 154

def first_page?
  previous_page.nil?
end

#highlights(multiple: false) ⇒ Object



178
179
180
181
182
# File 'lib/searchkick/results.rb', line 178

def highlights(multiple: false)
  hits.map do |hit|
    Hash[hit["highlight"].map { |k, v| [(options[:json] ? k : k.sub(/\.#{@options[:match_suffix]}\z/, "")).to_sym, multiple ? v : v.first] }]
  end
end

#hitsObject



166
167
168
169
170
171
172
# File 'lib/searchkick/results.rb', line 166

def hits
  if error
    raise Searchkick::Error, "Query error - use the error method to view it"
  else
    @response["hits"]["hits"]
  end
end

#last_page?Boolean

Returns:

  • (Boolean)


158
159
160
# File 'lib/searchkick/results.rb', line 158

def last_page?
  next_page.nil?
end

#misspellings?Boolean

Returns:

  • (Boolean)


188
189
190
# File 'lib/searchkick/results.rb', line 188

def misspellings?
  @options[:misspellings]
end

#model_nameObject



103
104
105
# File 'lib/searchkick/results.rb', line 103

def model_name
  klass.model_name
end

#next_pageObject



150
151
152
# File 'lib/searchkick/results.rb', line 150

def next_page
  current_page < total_pages ? (current_page + 1) : nil
end

#offset_valueObject Also known as: offset



140
141
142
# File 'lib/searchkick/results.rb', line 140

def offset_value
  (current_page - 1) * per_page + padding
end

#out_of_range?Boolean

Returns:

  • (Boolean)


162
163
164
# File 'lib/searchkick/results.rb', line 162

def out_of_range?
  current_page > total_pages
end

#paddingObject



131
132
133
# File 'lib/searchkick/results.rb', line 131

def padding
  options[:padding]
end

#per_pageObject Also known as: limit_value



126
127
128
# File 'lib/searchkick/results.rb', line 126

def per_page
  options[:per_page]
end

#previous_pageObject Also known as: prev_page



145
146
147
# File 'lib/searchkick/results.rb', line 145

def previous_page
  current_page > 1 ? (current_page - 1) : nil
end

#resultsObject



18
19
20
21
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
57
58
59
60
61
62
63
64
# File 'lib/searchkick/results.rb', line 18

def results
  @results ||= begin
    if options[:load]
      # results can have different types
      results = {}

      hits.group_by { |hit, _| hit["_type"] }.each do |type, grouped_hits|
        results[type] = results_query(type.camelize.constantize, grouped_hits).to_a.index_by { |r| r.id.to_s }
      end

      # sort
      hits.map do |hit|
        result = results[hit["_type"]][hit["_id"].to_s]
        if result && !(options[:load].is_a?(Hash) && options[:load][:dumpable])
          if hit["highlight"] && !result.respond_to?(:search_highlights)
            highlights = Hash[hit["highlight"].map { |k, v| [(options[:json] ? k : k.sub(/\.#{@options[:match_suffix]}\z/, "")).to_sym, v.first] }]
            result.define_singleton_method(:search_highlights) do
              highlights
            end
          end
        end
        result
      end.compact
    else
      hits.map do |hit|
        result =
          if hit["_source"]
            hit.except("_source").merge(hit["_source"])
          elsif hit["fields"]
            hit.except("fields").merge(hit["fields"])
          else
            hit
          end

        if hit["highlight"]
          highlight = Hash[hit["highlight"].map { |k, v| [base_field(k), v.first] }]
          options[:highlighted_fields].map { |k| base_field(k) }.each do |k|
            result["highlighted_#{k}"] ||= (highlight[k] || result[k])
          end
        end

        result["id"] ||= result["_id"] # needed for legacy reasons
        HashWrapper.new(result)
      end
    end
  end
end

#suggestionsObject



66
67
68
69
70
71
72
73
74
# File 'lib/searchkick/results.rb', line 66

def suggestions
  if response["suggest"]
    response["suggest"].values.flat_map { |v| v.first["options"] }.sort_by { |o| -o["score"] }.map { |o| o["text"] }.uniq
  elsif options[:term] == "*"
    []
  else
    raise "Pass `suggest: true` to the search method for suggestions"
  end
end

#tookObject



95
96
97
# File 'lib/searchkick/results.rb', line 95

def took
  response["took"]
end

#total_countObject Also known as: total_entries



117
118
119
# File 'lib/searchkick/results.rb', line 117

def total_count
  response["hits"]["total"]
end

#total_pagesObject Also known as: num_pages



135
136
137
# File 'lib/searchkick/results.rb', line 135

def total_pages
  (total_count / per_page.to_f).ceil
end

#with_highlights(multiple: false) ⇒ Object



184
185
186
# File 'lib/searchkick/results.rb', line 184

def with_highlights(multiple: false)
  results.zip(highlights(multiple: multiple))
end

#with_hitObject



174
175
176
# File 'lib/searchkick/results.rb', line 174

def with_hit
  results.zip(hits)
end