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

  • options (Hash)

    adapter-specific load options

See Also:

[View source]

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_index(index_name) ⇒ Object

[View source]

19
20
21
22
23
24
25
26
27
28
# File 'lib/chewy/search/loader.rb', line 19

def derive_index(index_name)
  index = (@derive_index ||= {})[index_name] ||= indexes_hash[index_name] ||
    indexes_hash[indexes_hash.keys.sort_by(&:length)
      .reverse.detect do |name|
                   index_name.match(/#{name}(_.+|\z)/)
                 end]
  raise Chewy::UndefinedIndex, "Can not find index named `#{index}`" unless index

  index
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 index present.

Parameters:

  • hits (Array<Hash>)

    ES hits array

Returns:

  • (Array<Object, nil>)

    the array of corresponding ORM/ODM objects

[View source]

40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/chewy/search/loader.rb', line 40

def load(hits)
  hit_groups = hits.group_by { |hit| hit['_index'] }
  loaded_objects = hit_groups.each_with_object({}) do |(index_name, hit_group), result|
    index = derive_index(index_name)
    ids = hit_group.map { |hit| hit['_id'] }
    loaded = index.adapter.load(ids, **@options.merge(_index: index.base_name))
    loaded ||= hit_group.map { |hit| index.build(hit) }

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

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