class Tire::Results::Collection

Attributes

facets[R]
max_score[R]
options[R]
suggestions[R]
time[R]
total[R]

Public Class Methods

new(response, options={}) click to toggle source
# File lib/tire/results/collection.rb, line 10
def initialize(response, options={})
  @response    = response
  @options     = options
  @time        = response['took'].to_i
  @total       = response['hits']['total'].to_i rescue nil
  @facets      = response['facets']
  @suggestions = Suggestions.new(response['suggest']) if response['suggest']
  @max_score   = response['hits']['max_score'].to_f rescue nil
  @wrapper     = options[:wrapper] || Configuration.wrapper
end

Public Instance Methods

[](*args) click to toggle source
Alias for: slice
__find_records_by_ids(klass, ids) click to toggle source
# File lib/tire/results/collection.rb, line 156
def __find_records_by_ids(klass, ids)
  @options[:load] === true ? klass.find(ids) : klass.find(ids, @options[:load])
end
__get_results_with_load(hits) click to toggle source
# File lib/tire/results/collection.rb, line 128
def __get_results_with_load(hits)
  return [] if hits.empty?

  records = {}
  @response['hits']['hits'].group_by { |item| item['_type'] }.each do |type, items|
    raise NoMethodError, "You have tried to eager load the model instances, " +
                         "but Tire cannot find the model class because " +
                         "document has no _type property." unless type

    begin
      klass = type.camelize.constantize
    rescue NameError => e
      raise NameError, "You have tried to eager load the model instances, but " +
                       "Tire cannot find the model class '#{type.camelize}' " +
                       "based on _type '#{type}'.", e.backtrace
    end

    records[type] = Array(__find_records_by_ids klass, items.map { |h| h['_id'] })
  end

  # Reorder records to preserve the order from search results
  @response['hits']['hits'].map do |item|
    records[item['_type']].detect do |record|
      record.id.to_s == item['_id'].to_s
    end
  end
end
__get_results_without_load(hits) click to toggle source
# File lib/tire/results/collection.rb, line 103
def __get_results_without_load(hits)
  if @wrapper == Hash
    hits
  else
    hits.map do |h|
      document = {}

      # Update the document with fields and/or source
      document.update h['_source'] if h['_source']
      document.update __parse_fields__(h['fields']) if h['fields']

      # Set document ID
      document['id'] = h['_id']

      # Update the document with meta information
      ['_score', '_type', '_index', '_version', 'sort', 'highlight', '_explanation'].each do |key|
        document.update key => h[key]
      end

      # Return an instance of the "wrapper" class
      @wrapper.new(document)
    end
  end
end
__parse_fields__(fields={}) click to toggle source

Handles _source prefixed fields properly: strips the prefix and converts fields to nested Hashes

# File lib/tire/results/collection.rb, line 83
def __parse_fields__(fields={})
  ( fields ||= {} ).clone.each_pair do |key,value|
    next unless key.to_s =~ %r_source/                 # Skip regular JSON immediately

    keys = key.to_s.split('.').reject { |n| n == '_source' }
    fields.delete(key)

    result = {}
    path = []

    keys.each do |name|
      path << name
      eval "result[:#{path.join('][:')}] ||= {}"
      eval "result[:#{path.join('][:')}] = #{value.inspect}" if keys.last == name
    end
    fields.update result
  end
  fields
end
as_json(options=nil) click to toggle source
# File lib/tire/results/collection.rb, line 65
def as_json(options=nil)
  to_a.map { |item| item.as_json(options) }
end
each(&block) click to toggle source

Iterates over the `results` collection

# File lib/tire/results/collection.rb, line 35
def each(&block)
  results.each(&block)
end
each_with_hit(&block) click to toggle source

Iterates over the `results` collection and yields the `result` object (Item or model instance) and the `hit` -- raw Elasticsearch response parsed as a Hash

# File lib/tire/results/collection.rb, line 43
def each_with_hit(&block)
  results.zip(@response['hits']['hits']).each(&block)
end
empty?() click to toggle source
# File lib/tire/results/collection.rb, line 47
def empty?
  results.empty?
end
error() click to toggle source
# File lib/tire/results/collection.rb, line 69
def error
  @response['error']
end
failure?() click to toggle source
# File lib/tire/results/collection.rb, line 77
def failure?
  ! success?
end
length() click to toggle source
Alias for: size
results() click to toggle source
# File lib/tire/results/collection.rb, line 21
def results
  return [] if failure?
  @results ||= begin
    hits = @response['hits']['hits'].map { |d| d.update '_type' => Utils.unescape(d['_type']) }
    unless @options[:load]
      __get_results_without_load(hits)
    else
      __get_results_with_load(hits)
    end
  end
end
size() click to toggle source
# File lib/tire/results/collection.rb, line 51
def size
  results.size
end
Also aliased as: length
slice(*args) click to toggle source
# File lib/tire/results/collection.rb, line 56
def slice(*args)
  results.slice(*args)
end
Also aliased as: []
success?() click to toggle source
# File lib/tire/results/collection.rb, line 73
def success?
  error.to_s.empty?
end
to_ary() click to toggle source
# File lib/tire/results/collection.rb, line 61
def to_ary
  results
end