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: [], **options) ⇒ Loader

Returns a new instance of Loader.

Parameters:

  • indexes (Array<Chewy::Index>) (defaults to: [])

    list of indexes to lookup types

  • options (Hash)

    adapter-specific load options

See Also:



14
15
16
17
# File 'lib/chewy/search/loader.rb', line 14

def initialize(indexes: [], **options)
  @indexes = indexes
  @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.

Parameters:

  • index (String)

    index name

  • type (String)

    type name

Returns:

Raises:



26
27
28
29
30
31
32
# File 'lib/chewy/search/loader.rb', line 26

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.values.first
  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.

Parameters:

Returns:

  • (Array<Object, nil>)

    the array of corresponding ORM/ODM objects



44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/chewy/search/loader.rb', line 44

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|
    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