lib/esse/repository/object_document_mapper.rb in esse-0.3.5 vs lib/esse/repository/object_document_mapper.rb in esse-0.4.0.rc1
- old
+ new
@@ -67,31 +67,69 @@
end
@collection_proc = collection_klass || block
end
+ # Expose the collection class to let external plugins and extensions to access it.
+ # @return [Class, nil] The collection class
+ # IDEA: When collection is defined as a block, it should setup a class with the block content.
+ def collection_class
+ return unless @collection_proc.is_a?(Class)
+
+ @collection_proc
+ end
+
# Wrap collection data into serialized batches
#
# @param [Hash] kwargs The context
# @return [Enumerator] The enumerator
# @yield [Array, **context] serialized collection and the optional context from the collection
- def each_serialized_batch(lazy_attributes: false, **kwargs)
+ def each_serialized_batch(eager_load_lazy_attributes: false, preload_lazy_attributes: false, **kwargs)
+ if kwargs.key?(:lazy_attributes)
+ warn 'The `lazy_attributes` option is deprecated. Use `eager_load_lazy_attributes` instead.'
+ eager_load_lazy_attributes = kwargs.delete(:lazy_attributes)
+ end
+
+ lazy_attrs_to_eager_load = lazy_document_attribute_names(eager_load_lazy_attributes)
+ lazy_attrs_to_search_preload = lazy_document_attribute_names(preload_lazy_attributes)
+ lazy_attrs_to_search_preload -= lazy_attrs_to_eager_load
+
each_batch(**kwargs) do |*args|
batch, collection_context = args
collection_context ||= {}
entries = [*batch].map { |entry| serialize(entry, **collection_context) }.compact
- if lazy_attributes
- attrs = lazy_attributes.is_a?(Array) ? lazy_attributes : lazy_document_attribute_names(lazy_attributes)
- attrs.each do |attr_name|
- retrieve_lazy_attribute_values(attr_name, entries).each do |doc_header, value|
- doc = entries.find { |d| doc_header.id.to_s == d.id.to_s && doc_header.type == d.type && doc_header.routing == d.routing }
- doc&.mutate(attr_name) { value }
+ lazy_attrs_to_eager_load.each do |attr_name|
+ retrieve_lazy_attribute_values(attr_name, entries).each do |doc_header, value|
+ doc = entries.find { |d| d.eql?(doc_header, match_lazy_doc_header: true) }
+ doc&.mutate(attr_name) { value }
+ end
+ end
+
+ if lazy_attrs_to_search_preload.any?
+ entries.group_by(&:routing).each do |routing, docs|
+ search_request = {
+ query: { ids: { values: docs.map(&:id) } },
+ size: docs.size,
+ _source: lazy_attrs_to_search_preload
+ }
+ search_request[:routing] = routing if routing
+ index.search(**search_request).response.hits.each do |hit|
+ header = [hit['_id'], hit['_routing'], hit['_type']]
+ next if header[0].nil?
+
+ hit.dig('_source')&.each do |attr_name, attr_value|
+ real_attr_name = lazy_document_attribute_names(attr_name).first
+ next if real_attr_name.nil?
+
+ doc = entries.find { |d| Esse.document_match_with_header?(d, *header) }
+ doc&.mutate(real_attr_name) { attr_value }
+ end
end
end
end
- yield entries, **kwargs
+ yield entries
end
end
# Wrap collection data into serialized documents
#
@@ -99,10 +137,10 @@
# GeosIndex.documents(id: 1).first
#
# @return [Enumerator] All serialized entries
def documents(**kwargs)
Enumerator.new do |yielder|
- each_serialized_batch(**kwargs) do |docs, **_collection_kargs|
+ each_serialized_batch(**kwargs) do |docs|
docs.each { |document| yielder.yield(document) }
end
end
end