Class: Mongoid::Association::EagerLoad::LookupPipeline Private
| Relationships & Source Files | |
| Inherits: | Object |
| Defined in: | lib/mongoid/association/eager_load/lookup_pipeline.rb |
Overview
Builds the aggregation pipeline that eager-loads a criteria's inclusions with $lookup.
It starts with the criteria's own match/sort/skip/limit, then lets each
root of the inclusion tree contribute its stages. This object owns the
stage-building helpers; how each inclusion contributes is the inclusion's
own business (see Inclusion).
For Band.eager_load(albums: :tracks) the result is roughly:
[ <criteria match / sort / skip / limit>,
{ '$lookup' => { # JoinedInclusion(:albums)
'from' => 'albums',
'localField' => '_id',
'foreignField' => 'band_id',
'as' => 'albums',
'pipeline' => [
{ '$sort' => {
'_id' => 1
} },
{ '$lookup' => { # JoinedInclusion(:tracks), nested
'as' => 'tracks',
'pipeline' => [
{ '$sort' => {
'_id' => 1
} }
]
} }
]
} } ]
Class Method Summary
- .new(criteria) ⇒ LookupPipeline constructor Internal use only
Instance Method Summary
-
#distribute(association, chain, lookup_stage) ⇒ Array<Hash>
Internal use only
Builds the stages that distribute a referenced inclusion living inside an embedded document onto that document.
-
#lookup_stage_for(association) ⇒ Hash
Internal use only
The $lookup stage for a referenced inclusion: its key fields, a discriminator match when the target shares its collection with sibling subclasses, and an order.
- #stages ⇒ Array<Hash> Internal use only
- #discriminator_match(association) private Internal use only
-
#lookup_fields(association)
private
Internal use only
When the association stores the foreign key on the current document (belongs_to, has_and_belongs_to_many) the local field is that key; for the others (has_many, has_one) the key is on the related document.
- #order(association) private Internal use only
Constructor Details
.new(criteria) ⇒ LookupPipeline
# File 'lib/mongoid/association/eager_load/lookup_pipeline.rb', line 42
def initialize(criteria) @criteria = criteria end
Instance Method Details
#discriminator_match(association) (private)
[ GitHub ]# File 'lib/mongoid/association/eager_load/lookup_pipeline.rb', line 100
def discriminator_match(association) target = association.klass { '$match' => { target.discriminator_key => { '$in' => target._types } } } end
#distribute(association, chain, lookup_stage) ⇒ Array<Hash>
Builds the stages that distribute a referenced inclusion living inside an embedded document onto that document.
# File 'lib/mongoid/association/eager_load/lookup_pipeline.rb', line 83
def distribute(association, chain, lookup_stage) EmbeddedDistributor.for(association: association, chain: chain, lookup_stage: lookup_stage).stages end
#lookup_fields(association) (private)
When the association stores the foreign key on the current document (belongs_to, has_and_belongs_to_many) the local field is that key; for the others (has_many, has_one) the key is on the related document.
# File 'lib/mongoid/association/eager_load/lookup_pipeline.rb', line 92
def lookup_fields(association) if association.stores_foreign_key? [ association.foreign_key, association.primary_key ] else [ association.primary_key, association.foreign_key ] end end
#lookup_stage_for(association) ⇒ Hash
The $lookup stage for a referenced inclusion: its key fields, a discriminator match when the target shares its collection with sibling subclasses, and an order. Children are added by the inclusion itself.
# File 'lib/mongoid/association/eager_load/lookup_pipeline.rb', line 61
def lookup_stage_for(association) local_field, foreign_field = lookup_fields(association) sub_pipeline = [] sub_pipeline << discriminator_match(association) if association.klass.hereditary? sub_pipeline << order(association) { '$lookup' => { 'from' => association.klass.collection.name, 'localField' => local_field, 'foreignField' => foreign_field, 'as' => association.name.to_s, 'pipeline' => sub_pipeline } } end
#order(association) (private)
[ GitHub ]# File 'lib/mongoid/association/eager_load/lookup_pipeline.rb', line 107
def order(association) unless association.order return { '$sort' => { '_id' => 1 } } end ordering = association.order ordering = { ordering => 1 } unless ordering.is_a?(Hash) { '$sort' => ordering } end
#stages ⇒ Array<Hash>
# File 'lib/mongoid/association/eager_load/lookup_pipeline.rb', line 47
def stages pipeline = @criteria.selector.to_pipeline pipeline.concat(@criteria..to_pipeline_for_lookup) InclusionTree.from(@criteria.inclusions, self).contribute_to(pipeline) pipeline end