class Searchkick::Results

Attributes

klass[R]
options[R]
response[R]

Public Class Methods

new(klass, response, options = {}) click to toggle source
# File lib/searchkick/results.rb, line 12
def initialize(klass, response, options = {})
  @klass = klass
  @response = response
  @options = options
end

Public Instance Methods

current_page() click to toggle source
# File lib/searchkick/results.rb, line 94
def current_page
  options[:page]
end
each_with_hit(&block) click to toggle source
# File lib/searchkick/results.rb, line 63
def each_with_hit(&block)
  results.zip(hits).each(&block)
end
entry_name() click to toggle source
# File lib/searchkick/results.rb, line 85
def entry_name
  model_name.human.downcase
end
facets() click to toggle source
# File lib/searchkick/results.rb, line 77
def facets
  response["facets"]
end
first_page?() click to toggle source
# File lib/searchkick/results.rb, line 126
def first_page?
  previous_page.nil?
end
hits() click to toggle source
# File lib/searchkick/results.rb, line 134
def hits
  @response["hits"]["hits"]
end
last_page?() click to toggle source
# File lib/searchkick/results.rb, line 130
def last_page?
  next_page.nil?
end
limit_value()
Alias for: per_page
model_name() click to toggle source
# File lib/searchkick/results.rb, line 81
def model_name
  klass.model_name
end
next_page() click to toggle source
# File lib/searchkick/results.rb, line 122
def next_page
  current_page < total_pages ? (current_page + 1) : nil
end
num_pages()
Alias for: total_pages
offset()
Alias for: offset_value
offset_value() click to toggle source
# File lib/searchkick/results.rb, line 112
def offset_value
  (current_page - 1) * per_page + padding
end
Also aliased as: offset
padding() click to toggle source
# File lib/searchkick/results.rb, line 103
def padding
  options[:padding]
end
per_page() click to toggle source
# File lib/searchkick/results.rb, line 98
def per_page
  options[:per_page]
end
Also aliased as: limit_value
prev_page()
Alias for: previous_page
previous_page() click to toggle source
# File lib/searchkick/results.rb, line 117
def previous_page
  current_page > 1 ? (current_page - 1) : nil
end
Also aliased as: prev_page
results() click to toggle source
# File lib/searchkick/results.rb, line 18
def results
  @results ||= begin
    if options[:load]
      # results can have different types
      results = {}

      hits.group_by { |hit, i| hit["_type"] }.each do |type, grouped_hits|
        records = type.camelize.constantize
        if options[:includes]
          if defined?(NoBrainer::Document) && records < NoBrainer::Document
            records = records.preload(options[:includes])
          else
            records = records.includes(options[:includes])
          end
        end
        results[type] = results_query(records, grouped_hits)
      end

      # sort
      hits.map do |hit|
        results[hit["_type"]].find { |r| r.id.to_s == hit["_id"].to_s }
      end.compact
    else
      hits.map do |hit|
        result =
          if hit["_source"]
            hit.except("_source").merge(hit["_source"])
          else
            hit.except("fields").merge(hit["fields"])
          end
        result["id"] ||= result["_id"] # needed for legacy reasons
        Hashie::Mash.new(result)
      end
    end
  end
end
suggestions() click to toggle source
# File lib/searchkick/results.rb, line 55
def suggestions
  if response["suggest"]
    response["suggest"].values.flat_map { |v| v.first["options"] }.sort_by { |o| -o["score"] }.map { |o| o["text"] }.uniq
  else
    raise "Pass `suggest: true` to the search method for suggestions"
  end
end
total_count() click to toggle source
# File lib/searchkick/results.rb, line 89
def total_count
  response["hits"]["total"]
end
Also aliased as: total_entries
total_entries()
Alias for: total_count
total_pages() click to toggle source
# File lib/searchkick/results.rb, line 107
def total_pages
  (total_count / per_page.to_f).ceil
end
Also aliased as: num_pages
with_details() click to toggle source
# File lib/searchkick/results.rb, line 67
def with_details
  each_with_hit.map do |model, hit|
    details = {}
    if hit["highlight"]
      details[:highlight] = Hash[hit["highlight"].map { |k, v| [(options[:json] ? k : k.sub(/\.analyzed\z/, "")).to_sym, v.first] }]
    end
    [model, details]
  end
end

Private Instance Methods

results_query(records, grouped_hits) click to toggle source
# File lib/searchkick/results.rb, line 140
def results_query(records, grouped_hits)
  if records.respond_to?(:primary_key) && records.primary_key
    # ActiveRecord
    records.where(records.primary_key => grouped_hits.map { |hit| hit["_id"] }).to_a
  elsif records.respond_to?(:all) && records.all.respond_to?(:for_ids)
    # Mongoid 2
    records.all.for_ids(grouped_hits.map { |hit| hit["_id"] }).to_a
  elsif records.respond_to?(:queryable)
    # Mongoid 3+
    records.queryable.for_ids(grouped_hits.map { |hit| hit["_id"] }).to_a
  elsif records.respond_to?(:unscoped) && records.all.respond_to?(:preload)
    # Nobrainer
    records.unscoped.where(:id.in => grouped_hits.map { |hit| hit["_id"] }).to_a
  else
    raise "Not sure how to load records"
  end
end