Overview
En esta guía, puedes aprender cómo personalizar la manera en que Mongoid devuelve los resultados de las consultas. MongoDB te permite realizar las siguientes acciones para modificar la forma en que aparecen los resultados:
Datos de muestra
Los ejemplos de esta guía utilizan el Band modelo, que representa una banda o grupo musical. La definición del modelo Band podría ser diferente para cada sección para demostrar diferentes funcionalidades de queries. Algunas secciones también utilizan el modelo Manager, que representa a una persona que gestionado una banda en particular, o el modelo Tour, que representa las presentaciones en vivo de la banda.
Retornar campos especificados
En MongoDB, laproyección es el proceso de especificar los campos que se incluirán o excluirán de los resultados. Mongoid proporciona los siguientes operadores para proyectar campos:
only: Especifica los campos a incluirwithout: Especifica los campos que se excluirán
Incluir campos
El método only recupera solo los campos especificados de la base de datos.
El siguiente código devuelve solo el campo name de los documentos en los que el valor del campo members es 4:
Band.where(members: 4).only(:name)
Nota
Campo _id
En MongoDB, el campo _id se incluye en los resultados incluso si no lo incluye explícitamente.
Si intentas hacer referencia a atributos que no se han cargado, Mongoid genera un error Mongoid::Errors::AttributeNotLoaded.
También puedes usar el método only para incluir campos de documentos incrustados.
Tenga en cuenta que el modelo Band incorpora varios objetos Tour. Puede proyectar campos del modelo Tour, como year, como se muestra en el siguiente código:
bands = Band.only(:name, 'tours.year')
Después, puedes acceder a los campos incrustados de los documentos devueltos:
# Returns the first Tour object from # the first Band in the results bands.first.tours.first
Se pueden pasar campos de asociaciones referenciadas al método only, pero la proyección se ignora al cargar los objetos incrustados. Mongoid carga todos los campos de las asociaciones referenciadas. Por ejemplo, al acceder al objeto incrustado Tour, como se muestra en el código anterior, Mongoid devuelve el objeto completo, no solo el campo year.
Nota
Si está conectado a una implementación que ejecuta MongoDB 4.4 o posterior, no puede especificar una asociación y sus campos en una proyección en la misma consulta.
Si un documento contiene asociaciones has_one o has_and_belongs_to_many y desea que Mongoid cargue esas asociaciones cuando llame al método only, debe incluir los campos con claves externas en la lista de atributos.
En el siguiente ejemplo, los modelos Band y Manager tienen una asociación has_and_belongs_to_many:
class Band include Mongoid::Document field :name, type: String has_and_belongs_to_many :managers end class Manager include Mongoid::Document has_and_belongs_to_many :bands end
El siguiente código demuestra cómo Mongoid puede cargar los objetos Manager asociados si incluye el campo manager_ids:
# Returns null Band.where(name: 'Astral Projection').only(:name).first.managers # Returns the first Manager object Band.where(name: 'Astral Projection').only(:name, :manager_ids).first.managers
Excluir campos
Puedes excluir explícitamente campos de los resultados utilizando el método without.
El siguiente código excluye el campo year de los objetos Band devueltos:
Band.where(members: 4).without(:year)
Importante
Campo _id
Mongoid requiere el campo _id para varias operaciones, por lo que no se puede excluir el campo _id ni el alias id de los resultados. Si pasas _id o id al método without, Mongoid lo ignorará.
Ordenar resultados
Se puede especificar el orden en el que Mongoid devuelve documentos usando los métodos order y order_by.
Estos métodos aceptan un hash que indica por qué campos debe ordenarse los documentos, y si se utiliza un orden ascendente o descendente para cada campo.
Puedes especificar la dirección de orden usando números enteros, símbolos o cadenas. Recomendamos utilizar la misma sintaxis de clasificación en toda la aplicación para mantener la coherencia. La siguiente lista proporciona cada sintaxis y muestra cómo ordenar los campos name y year:
Enteros
1(ascendente) y-1(descendente)Ejemplo:
Band.order(name: 1, year: -1)
Símbolos
:ascy:descEjemplo:
Band.order(name: :asc, year: :desc)
Cadenas
"asc"y"desc"Ejemplo:
Band.order_by(name: "asc", year: "desc")
El método order también admite las siguientes especificaciones de ordenamiento:
Matriz de matrices de dos elementos:
Strings
Ejemplo:
Band.order([['name', 'asc'], ['year', 'desc']])
Símbolos
Ejemplo:
Band.order([[:name, :asc], [:year, :desc]])
ascydescmétodos en símbolosEjemplo:
Band.order(:name.asc, :year.desc)
Sintaxis SQL
Ejemplo:
Band.order('name asc', 'year desc')
Tip
En lugar de utilizar order o order_by, también puede utilizar los métodos asc y desc para especificar órdenes de clasificación:
Band.asc('name').desc('year')
Cuando encadenas especificaciones de ordenamiento, la primera llamada define el primer orden de clasificación y la llamada más reciente define el último orden de clasificación, después de aplicar los ordenamientos previos.
Nota
Ordenación en Alcances
Si defines una alcance predeterminado en su modelo que incluye una especificación de ordenamiento, el ordenamiento del alcance tiene prioridad sobre el ordenamiento especificado en una consulta, porque el alcance predeterminado se evalúa primero.
Paginación de resultados
Mongoid proporciona los métodos de paginación limit, skip y batch_size que puedes usar en objetos Criteria. Las siguientes secciones describen cómo utilizar estos operadores.
Limitar el número de resultados
Puede utilizar el método limit para limitar el número de resultados que Mongoid devuelve.
El siguiente código recupera un máximo de 5 documentos:
Band.limit(5)
Nota
Alternativamente, puedes usar el método take para recuperar un número especificado de documentos de la base de datos:
Band.take(5)
Omitir resultados
Puedes omitir una cantidad específica de resultados utilizando el método skip, o su alias offset.
Si encadena una llamada limit a skip, el límite se aplica después de omitir los documentos, como se muestra en el siguiente ejemplo:
Band.skip(2).limit(5) # Skips the first two results and returns # the following five results
Tip
Cuando se realice la paginación, use skip en resultados ordenados para garantizar resultados coherentes.
El siguiente código omite los primeros 3 documentos al devolver los resultados:
Band.skip(3) # Equivalent Band.offset(3)
Generar lotes de resultados
Cuando se ejecutan grandes queries y se itera sobre los resultados de una query usando un método enumerador como Criteria#each, Mongoid utiliza automáticamente el comando MongoDB getMore para cargar los resultados en lotes. El tamaño de agrupar predeterminado es 1000, pero puedes establecer un valor diferente usando el método batch_size.
El siguiente código establece el tamaño del lote en 500:
Band.batch_size(500)
Asociaciones de carga ansiosas
Al consultar documentos con asociaciones, la carga anticipada permite cargar los documentos asociados al mismo tiempo que los documentos base, en lugar de cargarlos posteriormente de forma diferida. Esto reduce el número de consultas a la base de datos y mejora el rendimiento en cargas de trabajo con gran cantidad de asociaciones. Mongoid ofrece dos métodos para cargar anticipadamente los documentos asociados al consultar documentos con asociaciones: includes y eager_load.
incluye Método
El método includes carga las asociaciones mediante consultas separadas para cada una. El siguiente código carga las bandas y sus álbumes y sellos asociados mediante consultas separadas:
Band.where(name: 'The Beatles').includes({ albums: :songs }, :labels).first
Cuando se utiliza el método includes, Mongoid ejecuta una consulta en la clase base para obtener todos los documentos base y, a continuación, una consulta separada para cada asociación que carga de forma anticipada.
El ejemplo anterior ejecuta las siguientes consultas:
Una consulta para encontrar los documentos
BandUna consulta para cargar los documentos
AlbumasociadosUna consulta para cargar los documentos
LabelasociadosUna consulta para cargar los documentos
Songasociados
Método eager_load
El método eager_load utiliza la canalización de agregación de MongoDB con operadores $lookup para cargar todas las asociaciones en una sola consulta. El siguiente código utiliza una única consulta de canalización de agregación para cargar bandas y sus álbumes y sellos asociados, con etapas $lookup para cada asociación:
Band.where(name: 'The Beatles').eager_load({ albums: :songs }, :labels).first
Consideraciones sobre el rendimiento
Los métodos includes y eager_load realizan una carga anticipada, pero de maneras diferentes. El método includes ejecuta una consulta para los documentos base y luego consultas separadas para cada asociación. El método eager_load utiliza una única canalización de agregación con $lookup etapas para cargar las asociaciones.
El método eager_load ejecuta menos consultas y utiliza menos memoria que el método includes. Sin embargo, la eficiencia del método difiere según el tipo de asociaciones en sus documentos:
eager_loades más rápido parahas_many,has_and_belongs_to_manyy para cargar múltiples asociaciones en la mayoría de los conjuntos de datos.includeses más rápido parabelongs_to,has_oney asociaciones anidadas en la mayoría de los conjuntos de datos
Elija el método que mejor se adapte a su caso de uso y tipos de asociación.
Devolver datos sin procesar
Puedes devolver los resultados como hashes sin procesar sin crear instancias del modelo encadenando el método raw a tu consulta.
El siguiente código recupera los resultados de la consulta como hashes sin procesar:
Band.where(country: 'Argentina').raw
Por defecto, el método raw devuelve los documentos exactamente como Mongoid los recibe de la base de datos. Opcionalmente, puede convertir los campos de sus hashes de resultados a los tipos de las declaraciones de campos de su modelo configurando la opción typed a true en el método raw:
Band.where(country: 'Argentina').raw(typed: true)
Si realiza una consulta que devuelve resultados sin procesar y posteriormente desea convertir estos resultados en modelos, puede llamar a raw(false) en los resultados:
# Retrieves raw results results = Band.where(members: 4).raw # ... Perform actions on results # Returns instantiated model objects from raw results bands = results.raw(false).to_a
Información Adicional
Para obtener un catálogo completo de los métodos que puedes usar en Criteria objetos para modificar los resultados de la query, consulta la referencia del módulo Mongoid::Criteria::Queryable en la documentación de la API.
Para obtener más información sobre cómo construir consultas, consulte la guía Especificar una consulta de documento.
Para aprender sobre el modelado de datos de Mongoid, consulte las guías de Modelar los datos.