Módulo: Mongoid::Association::EagerLoadable

Incluido en:
Contextual::Memory, Contextual::Mongo, Contextual::Mongo::DocumentsLoader
Definido en:
lib/mongoid/association/eager_loadable.rb

Overview

Este módulo define el comportamiento de carga avanzada para los criterios.

Resumen del método de instancia colapsar

Detalles del método de instancia

#create_pipeline(current_assoc, mapping) ⇒ Object



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
# Archivo 'lib/mongoid/association/eager_loadable.rb', línea 147

def create_pipeline(asociación_actual, mapeo)
  # Construye una pipeline anidada para hijos y ordenamiento
  etapas de la canalización = []

  # Para belongs_to y has_and_belongs_to_many, la clave foránea se encuentra en el document actual
  # Para has_many/has_one, la clave externa se encuentra en el document relacionado
  si switch_local_and_foreign_fields?(asociación_actual)
    campo_local = asociación_actual.foreign_key
    foreign_field = asociación_actual.clave_primaria
  else
    campo_local = asociación_actual.clave_primaria
    foreign_field = asociación_actual.foreign_key
  end

  # Construye el campo 'as' con prefijo de ruta embebida si es necesario
  as_field = asociación_actual.Nombre.to_s

  etapa = {
    $lookup => {
      de'' => asociación_actual.klass.Colección.Nombre,
      'localField' => campo_local,
      'foreignField' => foreign_field,
      como => as_field
    }
  }

  # Agregar el orden si está definido en la asociación, o por defecto a _id para un orden consistente
  si asociación_actual.orden
    sort_spec = asociación_actual.orden.is_a?(encriptada) ? asociación_actual.orden : { asociación_actual.orden => 1 }
    etapas de la canalización << { '$sort' => sort_spec }
  else
    # Por defecto, ordenar por _id para mantener la coherencia en el orden de inserción
    etapas de la canalización << { '$sort' => { '_id' => 1 } }
  end

  # Añade búsquedas anidadas para asociaciones infantiles
  # Las asociaciones secundarias no necesitan el prefijo `embedded_path`, ya que se hace referencia a ellas desde el `document` consultado
  # Remueve esta clase del mapeo para evitar bucles infinitos con referencias circulares
  nombre_de_clase = asociación_actual.klass.to_s
  si child_assocs = mapeo.borrar(nombre_de_clase)
    child_assocs.cada hacer |niño|
      etapas de la canalización << create_pipeline(niño, mapeo)
    end
  end

  # Siempre agregar pipeline ya que siempre tenemos al menos $sort
  etapa[$lookup]['pipeline'] = etapas de la canalización

  etapa
end

#eager_load(docs) ⇒ arreglo<Mongoid::documento>

Carga las asociaciones para los documentos dados.

Parámetros:

Devuelve:



22
23
24
25
26
# Archivo 'lib/mongoid/association/eager_loadable.rb', línea 22

def eager_load(docs)
  docs.tocar hacer |d|
    precarga(criterios.inclusiones, d) si eager_loadable?
  end
end

#eager_load_with_lookupArray<Mongoid::Document>

Carga las asociaciones para los documentos proporcionados usando $lookup.

Si alguna de las colecciones asociadas reside en un clúster diferente al de la clase raíz, se recurre al comportamiento de #includes y se registra una advertencia.

Devuelve:



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# Archivo 'lib/mongoid/association/eager_loadable.rb', línea 34

def eager_load_with_lookup
  delincuentes = inclusive_interclúster
  si delincuentes.any?
    root_client = klass.client_name
    offender_list = delincuentes.map { |un(a)| "#{a.name} (#{a.klass.client_name})" }.unirse(', ')
    Mongoid.logger.advertencia(
      'eager_load no puede utilizar la agregación $lookup porque las siguientes asociaciones ' \
"residen en un clúster diferente a #{klass} (cliente: #{root_client}): " \
"#{offender_list}. Volviendo al comportamiento de #includes."
    )
    return carga_eager(docs_para_consulta_secundaria)
  end

  precargar_para_consulta(criterios)
end

#eager_loadable?true | false

Indica si el criterio tiene inclusiones de asociación que deben cargarse como eager loaded.

Devuelve:

  • (true | false)

    Indica si se utiliza la carga previa.



13
14
15
# Archivo 'lib/mongoid/association/eager_loadable.rb', línea 13

def eager_loadable?
  !criterios.inclusiones.¿vacío?
end

#preload(asociaciones, Docs) ⇒ Objeto

Carga las asociaciones de los documentos dados. Esto se realizará de manera recursiva para cargar las asociaciones de los documentos asociados de los documentos dados.

Parámetros:



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
# Archivo 'lib/mongoid/association/eager_loadable.rb', línea 57

def precarga(asociaciones, docs)
  assoc_map = asociaciones.group_by(&nombre_de_clase_inversa)
  docs_map = {}
  queue = [ klass.to_s ]

  # tener en cuenta la herencia de una colección única
  queue.push(klass.root_class.to_s) si klass != klass.root_class

  mientras klass = queue.turno
    Next a menos que como = assoc_map.borrar(klass)

    como.cada hacer |assoc|
      queue << assoc.nombre_de_clase

      # Si esta clase está anidada en el árbol de inclusión, solo cargar documentos
      # para la asociación anterior. Si no existe ninguna asociación principal,
      # incluiremos documentos de los documentos pasados a este método.
      ds = docs
      ds = assoc.parent_inclusions.map { |p| docs_map[p].to_a }.nivelar si assoc.parent_inclusions.longitud > 0

      res = assoc.relación.eager_loader([ assoc ], ds).Ejecutar

      docs_map[assoc.Nombre] ||= [].to_set
      docs_map[assoc.Nombre].fusionar(res)
    end
  end
end

#preload_for_lookup(criterio) ⇒ Object

Carga las asociaciones de los documentos dados. Esto se realizará de manera recursiva para cargar las asociaciones de los documentos asociados de los documentos dados.

Parámetros:



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
# Archivo 'lib/mongoid/association/eager_loadable.rb', línea 92

def preload_for_lookup(criterios)
  assoc_map = criterios.inclusiones.group_by(&nombre_de_clase_inversa)

  # hacer coincidir primero
  pipeline = criterios.selector.to_pipeline
  # luego ordenar, omitir, limitar
  pipeline.concat(criterios.opciones.to_pipeline_for_lookup)

  # tener en cuenta la herencia de una colección única
  root_class = klass.root_class

  si assoc_map[klass.to_s]
    assoc_map[klass.to_s].cada hacer |assoc|
      # Crea una copia del mapeo para cada asociación de nivel superior para evitar problemas de mutación
      pipeline << create_pipeline(assoc, assoc_map.dup)
    end
  end

  si klass != root_class && assoc_map[root_class.to_s]
    assoc_map[root_class.to_s].cada hacer |assoc|
      # Crea una copia del mapeo para cada asociación de nivel superior para evitar problemas de mutación
      pipeline << create_pipeline(assoc, assoc_map.dup)
    end
  end

  Entusiasta.Nuevo(criterios.inclusiones, [], true, pipeline).Ejecutar
end

#switch_local_and_foreign_fields?(acuerdo) ⇒ Booleano

Devuelve:



142
143
144
145
# Archivo 'lib/mongoid/association/eager_loadable.rb', línea 142

def switch_local_and_foreign_fields?(asociación)
  asociación.is_a?(Mongoid::Asociación::Referenciado::BelongsTo) ||
    asociación.is_a?(Mongoid::Asociación::Referenciado::HasAndBelongsToMany)
end