module Elasticsearch::Model::Adapter::Multiple::Records

Public Instance Methods

__adapter_for_klass(klass) click to toggle source

Returns the adapter registered for a particular `klass` or `nil` if not available

@api private

# File lib/elasticsearch/model/adapters/multiple.rb, line 130
def __adapter_for_klass(klass)
  Adapter.adapters.select { |name, checker| checker.call(klass) }.keys.first
end
__ids_by_type() click to toggle source

Returns the record IDs grouped by class based on type `_type`

Example:

{ Foo => ["1"], Bar => ["1", "5"] }

@api private

# File lib/elasticsearch/model/adapters/multiple.rb, line 91
def __ids_by_type
  ids_by_type = {}

  response.response["hits"]["hits"].each do |hit|
    type = __type_for_hit(hit)
    ids_by_type[type] ||= []
    ids_by_type[type] << hit[:_id]
  end
  ids_by_type
end
__no_type?(hit) click to toggle source
# File lib/elasticsearch/model/adapters/multiple.rb, line 122
def __no_type?(hit)
  hit[:_type].nil? || hit[:_type] == '_doc'
end
__records_by_type() click to toggle source

 Returns the collection of records grouped by class based on `_type`

Example:

{
  Foo  => {"1"=> #<Foo id: 1, title: "ABC"}, ...},
  Bar  => {"1"=> #<Bar id: 1, name: "XYZ"}, ...}
}

@api private
# File lib/elasticsearch/model/adapters/multiple.rb, line 56
def __records_by_type
  result = __ids_by_type.map do |klass, ids|
    records = __records_for_klass(klass, ids)
    ids     = records.map(&:id).map(&:to_s)
    [ klass, Hash[ids.zip(records)] ]
  end

  Hash[result]
end
__records_for_klass(klass, ids) click to toggle source

Returns the collection of records for a specific type based on passed `klass`

@api private

# File lib/elasticsearch/model/adapters/multiple.rb, line 70
def __records_for_klass(klass, ids)
  adapter = __adapter_for_klass(klass)

  case
    when Elasticsearch::Model::Adapter::ActiveRecord.equal?(adapter)
      klass.where(klass.primary_key => ids)
    when Elasticsearch::Model::Adapter::Mongoid.equal?(adapter)
      klass.where(:id.in => ids)
  else
    klass.find(ids)
  end
end
__type_for_hit(hit) click to toggle source

Returns the class of the model corresponding to a specific `hit` in Elasticsearch results

@see Elasticsearch::Model::Registry

@api private

# File lib/elasticsearch/model/adapters/multiple.rb, line 108
def __type_for_hit(hit)
  @@__types ||= {}

  key = "#{hit[:_index]}::#{hit[:_type]}" if hit[:_type] && hit[:_type] != '_doc'
  key = hit[:_index] unless key

  @@__types[key] ||= begin
    Registry.all.detect do |model|
      (model.index_name == hit[:_index] && __no_type?(hit)) ||
          (model.index_name == hit[:_index] && model.document_type == hit[:_type])
    end
  end
end
records() click to toggle source

Returns a collection of model instances, possibly of different classes (ActiveRecord, Mongoid, …)

@note The order of results in the Elasticsearch response is preserved

# File lib/elasticsearch/model/adapters/multiple.rb, line 35
def records
  records_by_type = __records_by_type

  records = response.response["hits"]["hits"].map do |hit|
    records_by_type[ __type_for_hit(hit) ][ hit[:_id] ]
  end

  records.compact
end