class Mongoid::Elasticsearch::Response

Attributes

facets[R]
max[R]
options[R]
response[R]
time[R]
total[R]

Public Class Methods

new(client, query, multi, model, options) click to toggle source
# File lib/mongoid/elasticsearch/response.rb, line 14
def initialize(client, query, multi, model, options)
  @client  = client
  @query   = query
  @multi   = multi
  @model   = model
  @wrapper = options[:wrapper]
  @options = options
end

Public Instance Methods

count() click to toggle source
# File lib/mongoid/elasticsearch/response.rb, line 110
def count
  # returns approximate counts, for now just using search_type: 'count',
  # which is exact
  # @total ||= @client.count(@query)['count']

  @total ||= @client.search(@query.merge(search_type: 'count'))['hits']['total']
end
each(&block) click to toggle source
# File lib/mongoid/elasticsearch/response.rb, line 98
def each(&block)
  results.each(&block)
end
error() click to toggle source
# File lib/mongoid/elasticsearch/response.rb, line 86
def error
  raw_response['error']
end
failure?() click to toggle source
# File lib/mongoid/elasticsearch/response.rb, line 94
def failure?
  !success?
end
hits() click to toggle source
# File lib/mongoid/elasticsearch/response.rb, line 46
def hits
  @hits ||= raw_response['hits']['hits']
end
inspect() click to toggle source
# File lib/mongoid/elasticsearch/response.rb, line 106
def inspect
  "#<Mongoid::Elasticsearch::Response @size:#{@results.nil? ? 'not run yet' : size} @results:#{@results.inspect} @raw_response=#{@raw_response}>"
end
length()
Alias for: size
perform!() click to toggle source
# File lib/mongoid/elasticsearch/response.rb, line 23
def perform!
  response = @client.search(@query)
  @options = options
  @time = response['took'].to_i
  @total = response['hits']['total'].to_i rescue nil
  @facets = response['facets']
  @max_score = response['hits']['max_score'].to_f rescue nil
  response
end
raw_response() click to toggle source
# File lib/mongoid/elasticsearch/response.rb, line 42
def raw_response
  @raw_response ||= perform!
end
results() click to toggle source
# File lib/mongoid/elasticsearch/response.rb, line 50
def results
  return [] if failure?
  @results ||= begin
    case @wrapper
    when :load
      if @multi
        multi_with_load
      else
        records = @model.find(hits.map { |h| h['_id'] })
        hits.map do |item|
          records.detect do |record|
            record.id.to_s == item['_id'].to_s
          end
        end
      end
    when :mash
      hits.map do |h|
        s = h.delete('_source')
        m = Hashie::Mash.new(h.merge(s))
        if defined?(Moped::BSON)
          m.id = Moped::BSON::ObjectId.from_string(h['_id'])
        else
          m.id = BSON::ObjectId.from_string(h['_id'])
        end
        m._id = m.id
        m
      end
    when :model
      multi_without_load
    else
      hits
    end

  end
end
size() click to toggle source
# File lib/mongoid/elasticsearch/response.rb, line 118
def size
  results.size
end
Also aliased as: length
success?() click to toggle source
# File lib/mongoid/elasticsearch/response.rb, line 90
def success?
  error.to_s.empty?
end
to_ary() click to toggle source
# File lib/mongoid/elasticsearch/response.rb, line 102
def to_ary
  results
end

Private Instance Methods

find_klass(type) click to toggle source
# File lib/mongoid/elasticsearch/response.rb, line 125
def find_klass(type)
  raise NoMethodError, "You have tried to eager load the model instances, " +
                       "but Mongoid::Elasticsearch cannot find the model class because " +
                       "document has no _type property." unless type

  begin
    klass = type.camelize.singularize.constantize
  rescue NameError => e
    raise NameError, "You have tried to eager load the model instances, but " +
                     "Mongoid::Elasticsearch cannot find the model class '#{type.camelize}' " +
                     "based on _type '#{type}'.", e.backtrace
  end
end
multi_with_load() click to toggle source
# File lib/mongoid/elasticsearch/response.rb, line 139
def multi_with_load
  return [] if hits.empty?

  records = {}
  hits.group_by { |item| item['_type'] }.each do |type, items|
    klass = find_klass(type)
    records[type] = klass.find(items.map { |h| h['_id'] })
  end

  # Reorder records to preserve the order from search results
  hits.map do |item|
    records[item['_type']].detect do |record|
      record.id.to_s == item['_id'].to_s
    end
  end
end
multi_without_load() click to toggle source
# File lib/mongoid/elasticsearch/response.rb, line 156
      def multi_without_load
        hits.map do |h|
          klass = find_klass(h['_type'])
          h[:_highlight] = h.delete('highlight') if h.key?('highlight')
          source = h.delete('_source')
          if defined?(Moped::BSON)
            source.each do |k,v|
              if v.is_a?(Hash) && v.has_key?("$oid")
                source[k] = Moped::BSON::ObjectId.from_string(v["$oid"])
              end
            end
          else
            source.each do |k,v|
              if v.is_a?(Hash) && v.has_key?("$oid")
                source[k] = BSON::ObjectId.from_string(v["$oid"])
              end
            end
          end
          begin
            m = klass.new(h.merge(source))
            if defined?(Moped::BSON)
              m.id = Moped::BSON::ObjectId.from_string(h['_id'])
            else
              m.id = BSON::ObjectId.from_string(h['_id'])
            end
          rescue Mongoid::Errors::UnknownAttribute
            klass.class_eval <<-RUBY, __FILE__, __LINE__+1
              attr_accessor :_type, :_score, :_source, :_highlight
            RUBY
            m = klass.new(h.merge(source))
          end
          m.new_record = false
          m
        end
      end