Módulo: Mongoid::Association::EagerLoadable
- Definido em:
- lib/mongoid/association/eager_loadable.rb
Visão geral
Este módulo define o comportamento de carregamento ansioso para critérios.
Recolhimento do Resumo do método de instância
- #create_pipeline(current_assoc, mapeamento) ➤ Objeto
-
#hookid:: >Docs<Mongoid::Document>
Carregue as associações para os documentos fornecidos.
-
#concerns_load_with_lookup ➤ Array<Mongoid::Document>
Carregue as associações para os documentos fornecidos usando $lookup.
-
#concerns_loadable? ➤ verdadeiro | false
Indica se os critérios têm inclusões de associação que devem ser carregadas antecipadamente.
-
#preload(associations, Docs) ⇒ Object
Carregue as associações para os documentos fornecidos.
-
#preload_for_lookup(critérios) ➤ Objeto
Carregue as associações para os documentos fornecidos.
- #switch_local_and_foreign_fields?(associação) ➤ Booleano
Detalhes do método de instância
#create_pipeline(current_assoc, mapeamento) ➤ Objeto
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
# File 'lib/mongoid/association/eager_loadable.rb', linha 147 def create_pipeline(current_assoc, mapeamento) # Criar pipeline aninhado para crianças e pedidos pipeline_stages = [] # Para requires_to e has_and_belongs_to_many, a chave estrangeira está no document atual # Para has_many/has_one, a chave estrangeira está no document relacionado se switch_local_and_foreign_fields?(current_assoc) local_field = current_assoc.foreign_key foreign_field = current_assoc.primary_key mais local_field = current_assoc.primary_key foreign_field = current_assoc.foreign_key end # Construa o campo 'as' com prefixo de caminho embutido, se necessário as_field = current_assoc.name.to_s estágio = { '$lookup' => { 'de' => current_assoc.classe.collection.name, 'localField' => local_field, 'foreignField' => foreign_field, 'como' => as_field } } # Adicione ordenação se definido na associação, ou padronize para _id para ordenação consistente se current_assoc.order sort_spec = current_assoc.order.is_a?(Hash) ? current_assoc.order : { current_assoc.order => 1 } pipeline_stages << { '$sort' => sort_spec } mais # Padrão para classificação por _id para manter a consistência do pedido de inserção pipeline_stages << { '$sort' => { '_id' => 1 } } end # Adicionar pesquisas aninhadas para associações filhas # Associações filhas não precisam do prefixo embedded_path, pois são referenciadas no document pesquisado # Remova esta classe do mapeamento para evitar loops infinitos com referências circulares class_name = current_assoc.classe.to_s se child_assocs = mapeamento.excluir(class_name) child_assocs.cada fazer |criança| pipeline_stages << create_pipeline(criança, mapeamento) end end # Sempre adicione pipeline, pois sempre temos pelo menos $sort estágio['$lookup']['pipeline'] = pipeline_stages estágio end |
#concerns_load(Docs) ➤ Array <Mongoid::Document>
Carregue as associações para os documentos fornecidos.
22 23 24 25 26 |
# File 'lib/mongoid/association/eager_loadable.rb', linha 22 def modified_load(Docs) Docs.toque fazer |d| pré-carregar(critério.inclusões, d) se ans_loadable? end end |
#eager_load_with_lookup ⇒ Array<Mongoid::Document>
Carregue as associações para os documentos fornecidos usando $lookup.
Se alguma das coleções associadas residir em um cluster diferente da classe raiz , volte ao comportamento #includes e registre um log um aviso.
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/mongoid/association/eager_loadable.rb', linha 34 def ans_load_with_lookup Infratores = cross_cluster_incluses se Infratores.algum? root_client = classe.client_name ofender_list = Infratores.map { |uma| "#{a.name} (#{a.klass.client_name})" }.juntar(', ') Mongoid.logger.AVISAR( 'eager_load não pode usar a agregação $lookup porque as seguintes associações " \ "residem em um cluster diferente de #{klass} (cliente: #{root_client}): " \ "#{offender_list}. Retornando ao comportamento #includes." ) return priority_for_lookup(docs_for_lookup_fallback) end preload_for_lookup(criteria) end |
#concerns_loadable? ➤ verdadeiro | false
Indica se os critérios têm inclusões de associação que devem ser carregadas antecipadamente.
13 14 15 |
# File 'lib/mongoid/association/eager_loadable.rb', linha 13 def ans_loadable? !critério.inclusões.vazio? end |
#preload(associations, Docs) ⇒ Object
Carregue as associações para os documentos fornecidos. Isso será feito recursivamente para carregar as associações dos document associados dos document fornecidos.
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/mongoid/association/eager_loadable.rb', linha 57 def pré-carregar(Associações, Docs) assoc_map = Associações.group_by(&:inverse_class_name) docs_map = {} fila = [ classe.to_s ] # account para herança de collection única fila.push(classe.root_class.to_s) se classe != classe.root_class enquanto classe = fila.mudança próximo a menos que como = assoc_map.excluir(classe) como.cada fazer |assoc| fila << assoc.class_name # Se esta classe estiver aninhada na árvore de inclusão, carregue apenas documentos # para a associação acima dela. Se não houver associação de pais, # incluiremos documentos dos documentos passados para esse método. ds = Docs ds = assoc.parent_incluses.map { |p| docs_map[p].to_a }.achatar se assoc.parent_incluses.Tamanho > 0 res = assoc.relação.ans_loader([ assoc ], ds).EXECUTAR docs_map[assoc.name] ||= [].to_set docs_map[assoc.name].mesclar(res) end end end |
#preload_for_lookup(critérios) ⇒ Objeto
Carregue as associações para os documentos fornecidos. Isso será feito recursivamente para carregar as associações dos document associados dos document fornecidos.
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/mongoid/association/eager_loadable.rb', linha 92 def preload_for_lookup(critério) assoc_map = critério.inclusões.group_by(&:inverse_class_name) # corresponder primeiro gasoduto = critério.seletor.to_pipeline # então classificar, pular, limitar gasoduto.concat(critério..to_pipeline_for_lookup) # account para herança de collection única root_class = classe.root_class se assoc_map[classe.to_s] assoc_map[classe.to_s].cada fazer |assoc| # Criar uma cópia do mapeamento para cada associação de nível superior para evitar problemas de mutação gasoduto << create_pipeline(assoc, assoc_map.dup) end end se classe != root_class && assoc_map[root_class.to_s] assoc_map[root_class.to_s].cada fazer |assoc| # Criar uma cópia do mapeamento para cada associação de nível superior para evitar problemas de mutação gasoduto << create_pipeline(assoc, assoc_map.dup) end end Ansioso.Novo(critério.inclusões, [], true, gasoduto).EXECUTAR end |
#switch_local_and_foreign_fields?(associação) ⇒ Booleano
142 143 144 145 |
# File 'lib/mongoid/association/eager_loadable.rb', linha 142 def switch_local_and_foreign_fields?(associação) associação.is_a?(Mongoid::associação::Referenciado::Pertence a) || associação.is_a?(Mongoid::associação::Referenciado::Tem e pertence a muitos) end |