Class: Chewy::Search::Loader

Inherits:
Object
  • Object
show all
Defined in:
lib/chewy/search/loader.rb

Overview

This class is used for two different purposes: load ORM/ODM source objects.

Instance Method Summary collapse

Constructor Details

#initialize(indexes: [], only: [], except: [], **options) ⇒ Loader

Returns a new instance of Loader.



16
17
18
19
20
21
# File 'lib/chewy/search/loader.rb', line 16

def initialize(indexes: [], only: [], except: [], **options)
  @indexes = indexes
  @only = Array.wrap(only).map(&:to_s)
  @except = Array.wrap(except).map(&:to_s)
  @options = options
end

Instance Method Details

#derive_type(index, type) ⇒ Chewy::Type

Returns a Type object for index name and type name passed. Caches the result for each pair to make lookup faster.

Raises:



30
31
32
33
34
35
36
# File 'lib/chewy/search/loader.rb', line 30

def derive_type(index, type)
  (@derive_type ||= {})[[index, type]] ||= begin
    index_class = derive_index(index)
    raise Chewy::UnderivableType, "Can not find index named `#{index}`" unless index_class
    index_class.type_hash[type] or raise Chewy::UnderivableType, "Index `#{index}` doesn`t have type named `#{type}`"
  end
end

#load(hits) ⇒ Array<Object, nil>

For each passed hit this method loads an ORM/ORD source object using hit['_id']. The returned array is exactly in the same order as hits were. If source object was not found for some hit, nil will be returned at the corresponding position in array.

Records/documents are loaded in an efficient manner, performing a single query for each type present.



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/chewy/search/loader.rb', line 48

def load(hits)
  hit_groups = hits.group_by { |hit| [hit['_index'], hit['_type']] }
  loaded_objects = hit_groups.each_with_object({}) do |((index_name, type_name), hit_group), result|
    next if skip_type?(type_name)

    type = derive_type(index_name, type_name)
    ids = hit_group.map { |hit| hit['_id'] }
    loaded = type.adapter.load(ids, **@options.merge(_type: type))
    loaded ||= hit_group.map { |hit| type.build(hit) }

    result.merge!(hit_group.zip(loaded).to_h)
  end

  hits.map { |hit| loaded_objects[hit] }
end