Overview
En esta guía, puedes aprender a especificar una query usando Mongoid.
Puedes perfeccionar el conjunto de documentos que una query devuelve creando un filtro de query. Un filtro de query es una expresión que especifica los criterios de búsqueda que MongoDB utiliza para coincidir documentos en una operación de lectura o escritura. Cuando crees un filtro de query, puedes solicitar al driver que busque documentos que coincidan exactamente con tu query, o puedes crear filtros de query para Express criterios de coincidencia más complejos.
Mongoid proporciona un lenguaje específico de dominio (DSL) para query similar al utilizado en Active Record.
Datos de muestra
Los ejemplos de esta guía utilizan el Band modelo, lo que representa a una banda o grupo musical. La definición del modelo Band puede ser diferente para cada sección para demostrar diferentes funcionalidades de query. Algunas secciones pueden emplear otros modelos para demostrar la funcionalidad de query.
Consultas en Mongoid
Los métodos de consulta de Mongoid devuelven objetos Mongoid::Criteria, que son contenedores encadenables y evaluados de manera perezosa para la API de queries de MongoDB. Las consultas se ejecutan cuando se itera a través de los resultados. El siguiente ejemplo demuestra el tipo de retorno de una query simple:
# Creates a simple query Band.where(name: "Deftones") # Returns a Criteria object # => #<Mongoid::Criteria # selector: {"name"=>"Deftones"} # options: {} # class: Band # embedded: false> # Evaluate the query by converting to JSON Band.where(name: "Deftones").to_json # Returns matching documents # => [{"_id":"...","name":"Deftones"}]
Puedes usar métodos como first y last para devolver documentos individuales. También puedes iterar un objeto Criteria usando métodos como each o map para recuperar documentos desde el servidor. Puedes usar to_json para convertir un objeto Criteria a JSON.
Tip
Encadenamiento de métodos
Si encadenas otros métodos de query en un objeto Criteria existente, Mongoid combina los criterios de filtro.
Crear un filtro de query
Esta sección describe los patrones de sintaxis que puedes utilizar para crear criterios de filtro. Puedes especificar consultas en Mongoid utilizando cualquiera de los siguientes patrones de sintaxis:
Sintaxis de campos
Sintaxis de la API de query
Sintaxis del operador de símbolos
Nota
Comportamientos de sintaxis
Estas sintaxis admiten la consulta de documentos incrustados mediante la notación de puntos. Las sintaxis también respetan alias de campos y tipos de campos, si el campo que se consulta está definido en la clase del modelo.
Las ejemplos en esta sección utilizan la siguiente definición del modelo:
class Band include Mongoid::Document field :name, type: String field :founded, type: Integer field :m, as: :member_count, type: Integer embeds_one :manager end class Manager include Mongoid::Document embedded_in :band field :name, type: String end
Sintaxis de campo
La sintaxis de consultas de campos utiliza los hashes básicos de Ruby. Las claves pueden ser símbolos o cadenas y corresponden a nombres de campo en los documentos de MongoDB.
El siguiente código muestra dos queries equivalentes que utilizan la sintaxis de query de campo para recuperar documentos en los que el valor del campo name es 'Depeche Mode':
Band.where(name: 'Depeche Mode') Band.where('name' => 'Depeche Mode')
Sintaxis de la API Query
Se puede especificar un operador de API de consulta en cualquier campo utilizando la sintaxis de hash, como se muestra en las siguientes consultas equivalentes:
Band.where(founded: {'$gt' => 1980}) Band.where('founded' => {'$gt' => 1980})
Sintaxis del Operador de Símbolos
Puedes especificar los operadores de Query API como métodos sobre símbolos para el respectivo nombre de campo, como se muestra en el siguiente código:
Band.where(:founded.gt => 1980)
Query sobre diferentes tipos de campos
Esta sección describe cómo realizar consultas en campos con diferentes tipos de valores.
Campos definidos
Para hacer una query en un campo, el campo no necesita estar en la definición de la clase modelo. Sin embargo, si un campo está definido en la clase del modelo, Mongoid fuerza los valores de la query para que coincidan con los tipos de campo definidos al construir la query.
El siguiente código especifica un valor de string cuando se consulta en el campo founded. Debido a que el founded campo está definido en la Integer clase de modelo para tener valores, Mongoid convierte la cadena '2020' en 2020 al realizar la query:
Band.where(founded: '2020')
Para obtener más información sobre cómo definir campos en Mongoid, consulte la Usa los tipos de campo BSON guía.
Valores brutos
Para evitar el comportamiento de coerción de tipo de consulta de Mongoid y consultar directamente el valor de tipo bruto en la base de datos, encapsula el valor de la consulta en la clase Mongoid::RawValue, como se muestra en el siguiente código:
Band.where(founded: Mongoid::RawValue('2020'))
Alias de campo
Las consultas siguen los nombres de los campos de almacenamiento y los alias de campos que podrías haber configurado en la definición de la clase del modelo.
Los campos id y _id son alias, por lo que puedes utilizar cualquiera de los nombres de campo en las consultas:
Band.where(id: '5ebdeddfe1b83265a376a760') Band.where(_id: '5ebdeddfe1b83265a376a760')
Documentos incrustados
Para consultar acerca de los valores de los campos de documentos incrustados, puedes utilizar la notación de puntos. El siguiente código recupera los documentos en los que el campo name del documento incorporado Manager es 'Smith':
Band.where('manager.name' => 'Smith')
El siguiente código demuestra cómo usar un operador de símbolo al consultar un campo integrado:
Band.where(:'manager.name'.ne => 'Smith')
Nota
Las queries siempre retornan instancias del modelo de nivel superior, incluso si todas las condiciones hacen referencia a campos de documentos incrustados.
Operaciones lógicas
Mongoid admite las siguientes operaciones lógicas en los objetos Criteria:
andornornot
Estos métodos toman uno o más hashes de condiciones u otro objeto Criteria como sus argumentos. La operación not tiene una versión sin argumentos.
El siguiente código demuestra cómo utilizar las operaciones lógicas en las queries:
# Uses "and" to combine criteria Band.where(label: 'Trust in Trance').and(name: 'Astral Projection') # Uses "or" to specify criteria Band.where(label: 'Trust in Trance').or(Band.where(name: 'Astral Projection')) # Uses "not" to specify criteria Band.not(label: 'Trust in Trance', name: 'Astral Projection') # Uses "not" without arguments Band.not.where(label: 'Trust in Trance', name: 'Astral Projection')
Nota
Parámetros de arreglo
Para garantizar la compatibilidad retroactiva con versiones anteriores de Mongoid, los métodos de operación lógica aceptan arreglos de parámetros, que se "aplanan" (flattened) para obtener los criterios.
El paso de arreglos a operaciones lógicas está obsoleto y podría eliminarse en una versión futura.
Las siguientes consultas producen las mismas condiciones:
# Conditions passed to separate "and" calls Band.and(name: 'Sun Kil Moon').and(member_count: 2) # Multiple conditions in the same "and" call Band.and({name: 'Sun Kil Moon'}, {member_count: 2}) # Multiple conditions in an array - Deprecated Band.and([{name: 'Sun Kil Moon'}, {member_count: 2}]) # Condition in "where" and a scope Band.where(name: 'Sun Kil Moon').and(Band.where(member_count: 2)) # Condition in "and" and a scope Band.and({name: 'Sun Kil Moon'}, Band.where(member_count: 2)) # Scope as an array element, nested arrays - Deprecated Band.and([Band.where(name: 'Sun Kil Moon'), [{member_count: 2}]])
Combinaciones de operadores
Los operadores lógicos tienen la misma semántica que los de Active Record.
Cuando se especifican condiciones en el mismo campo varias veces, todas las condiciones se añaden a los criterios, como demuestra las consultas del siguiente código:
# Combines as "and" Band.where(name: 'Swans').where(name: 'Feist') # Combines as "or" Band.where(name: 'Swans').or(name: 'Feist')
Las operaciones any_of, none_of, nor y not se comportan de manera similar.
Cuando usas los operadores lógicos and, or, y nor, estos actúan sobre los criterios establecidos hasta ese punto:
# "or" applies to the first condition, and the second is combined # as "and" Band.or(name: 'Sun').where(label: 'Trust') # Same as previous example - "where" and "and" are aliases Band.or(name: 'Sun').and(label: 'Trust') # Same operator can be stacked any number of times Band.or(name: 'Sun').or(label: 'Trust') # The last label condition is added to the top level as "and" Band.where(name: 'Sun').or(label: 'Trust').where(label: 'Feist') # Interpreted query: # {"$or"=>[{"name"=>"Sun"}, {"label"=>"Trust"}], "label"=>"Feist"}
no Comportamiento
Puedes utilizar el método not sin argumentos, en cuyo caso niega la siguiente condición que se especifique. El método not puede llamarse con una o más condiciones hash u objetos Criteria, los cuales se niegan y se añaden a los criterios.
Los siguientes ejemplos demuestran el comportamiento de not:
# "not" negates "where" Band.not.where(name: 'Best') # The second "where" is added as "$and" Band.not.where(name: 'Best').where(label: /Records/) # "not" negates its argument Band.not(name: 'Best')
Nota
No puedes usar el operador $not en MongoDB con un argumento de cadena. Mongoid utiliza el operador $ne para lograr la negación:
# String negation - uses "$ne" Band.not.where(name: 'Best') # Regex negation - uses "$not" Band.not.where(name: /Best/)
De manera similar a and, la operación not niega condiciones individuales para criterios de campo simples. Para condiciones complejas y cuando un campo ya tiene una condición definida, Mongoid emula $not mediante el uso de un constructo {'$and' => [{'$nor' => ...}]}, porque MongoDB solo admite el operador $not por campo, en lugar de globalmente:
# Simple condition Band.not(name: /Best/) # Complex conditions Band.where(name: /Best/).not(name: 'Astral Projection') # Symbol operator syntax Band.not(:name.ne => 'Astral Projection')
Si utilizas not con arreglos o expresiones regulares, consulta las limitaciones de $not en el manual del servidor.
Construcción incremental de consultas
Por defecto, cuando se agregan condiciones a una query, Mongoid considera cada condición completa e independiente de cualquier otra condición presente en la query. Por ejemplo, llamar a in dos veces agrega dos condiciones $in independientes:
Band.in(name: ['a']).in(name: ['b']) # Interpreted query: # {"name"=>{"$in"=>["a"]}, "$and"=>[{"name"=>{"$in"=>["b"]}}]}
Algunos métodos del operador admiten la construcción de la condición de forma incremental. Cuando añades una condición que usa uno de los operadores soportados, Mongoid verifica si ya hay una condición en el mismo campo usando el mismo operador. Si es así, las expresiones del operador se combinan según la estrategia de fusión especificada. La siguiente sección describe las estrategias de fusión disponibles.
Estrategias de fusión
Mongoid proporciona las siguientes estrategias de fusión:
Supersede: la nueva instancia del operador sustituye cualquier condición existente en el mismo campo utilizando el mismo operador.
Intersección: Si ya existe una condición que usa el mismo operador en el mismo campo, los valores de la condición existente se intersectan con los valores de la nueva condición y el resultado se almacena como el valor del operador.
Unión: Si ya existe una condición que utiliza el mismo operador en el mismo campo, los valores de la nueva condición se suman a los valores de la condición existente y el resultado se almacena como el valor del operador.
El siguiente código muestra cómo las estrategias de fusión generan criterios utilizando in como operador de ejemplo:
Band.in(name: ['a']).override.in(name: ['b']) # Interpreted query: # {"name"=>{"$in"=>["b"]}} Band.in(name: ['a', 'b']).intersect.in(name: ['b', 'c']) # Interpreted query: # {"name"=>{"$in"=>["b"]}} Band.in(name: ['a']).union.in(name: ['b']) # Interpreted query: # {"name"=>{"$in"=>["a", "b"]}}
La estrategia se solicita llamando a override, intersect o union en una instancia Criteria. La estrategia solicitada se aplica al siguiente método de condición llamado en la query. Si el siguiente método de condición llamado no admite soporte de estrategias de fusión, la estrategia se reinicia, como se muestra en el siguiente ejemplo:
Band.in(name: ['a']).union.ne(name: 'c').in(name: ['b']) # Interpreted query: # {"name"=>{"$in"=>["a"], "$ne"=>"c"}, "$and"=>[{"name"=>{"$in"=>["b"]}}]}
Debido a que ne no admite estrategias de fusión, la estrategia union se ignora y restablece. Entonces, cuando in se invoca por segunda vez, no hay una estrategia activa.
Advertencia
Las estrategias de combinación asumen que las condiciones previas se han agregado al nivel superior de la query. Sin embargo, este no siempre es el caso, ya que las condiciones podrían estar anidadas bajo una cláusula $and. El uso de estrategias de fusión con criterios complejos puede generar consultas incorrectas.
Métodos de operador admitidos
Los siguientes métodos de operador admiten estrategias de fusión:
allinnin
El conjunto de métodos podría ampliarse en futuras versiones de Mongoid. Para garantizar la compatibilidad futura, invoca un método de estrategia solo cuando la próxima llamada de método sea un operador que admita estrategias de fusión.
Las estrategias de combinación se aplican solo cuando se añaden condiciones mediante los métodos designados. En el siguiente ejemplo, la estrategia de fusión no se aplica porque la segunda condición se añade como where, no utilizando in:
Band.in(name: ['a']).union.where(name: {'$in' => 'b'}) # Interpreted query: # {"foo"=>{"$in"=>["a"]}, "$and"=>[{"foo"=>{"$in"=>"b"}}]}
Expansión del valor del operador
Los métodos de operador que admiten estrategias de fusión utilizan Array como su tipo de valor. Mongoid amplía los tipos compatibles con Array, como un Range, cuando se utilizan con estos métodos operadores.
El siguiente ejemplo demuestra cómo puedes pasar un objeto Range como valor de query al utilizar el método in:
Band.in(year: 1950..1960) # Interpreted query: # {"year"=>{"$in"=>[1950, 1951, 1952, 1953, 1954, 1955, 1956, 1957, 1958, 1959, 1960]}}
Mongoid envuelve valores que no sonArray en arreglos, como se muestra en el siguiente ejemplo:
Band.in(year: 1950) # Interpreted query: {"year"=>{"$in"=>[1950]}}
Coincidencia de elementos
Puedes utilizar el método elem_match para hacer coincidir documentos que contengan un campo de arreglo con al menos un elemento que cumpla con todos los criterios de query especificados.
El siguiente ejemplo crea un documento de muestra que contiene un campo de arreglo. Luego, usa el método elem_match para hacer coincidir documentos en los que el campo de arreglo tour contiene una entrada en la que el valor city es 'London':
aerosmith = Band.create!(name: 'Aerosmith', tours: [ {city: 'London', year: 1995}, {city: 'New York', year: 1999}, ]) swans = Band.create!(name: 'Swans', tours: [ {city: 'Milan', year: 2014}, {city: 'Montreal', year: 2015}, ]) # Returns only "Aerosmith" Band.elem_match(tours: {city: 'London'})
Asociaciones
Puedes utilizar el método elem_match para igualar asociaciones anidadas.
Este ejemplo utiliza los siguientes modelos que definen una asociación embebida entre Band y Tour:
class Band include Mongoid::Document field :name, type: String embeds_many :tours end class Tour include Mongoid::Document field :city, type: String field :year, type: Integer embedded_in :band end
El siguiente código crea un objeto Band e incrusta objetos Tour, luego utiliza el método elem_match para hacer consultas en el campo city:
aerosmith = Band.create!(name: 'Aerosmith') Tour.create!(band: aerosmith, city: 'London', year: 1995) Tour.create!(band: aerosmith, city: 'New York', year: 1999) # Returns the "Aerosmith" document Band.elem_match(tours: {city: 'London'})
Nota
No puedes utilizar elem_match en asociaciones no incorporadas porque MongoDB no realiza una operación de unión en las colecciones. Si realizas esta query, las condiciones se añaden a la colección que es la fuente de la asociación no embebida en vez de a la colección de la asociación.
Puede utilizar elem_match para query asociaciones anidadas recursivamente, como se muestra en el siguiente ejemplo:
class Tag include Mongoid::Document field name:, type: String recursively_embeds_many end # Creates the root Tag root = Tag.create!(name: 'root') # Adds embedded Tags sub1 = Tag.new(name: 'sub_tag_1', child_tags: [Tag.new(name: 'sub_sub_tag_1')]) root.child_tags << sub1 root.child_tags << Tag.new(name: 'sub_tag_2') root.save! # Searches for Tag in which one child Tag tame is "sub_tag_1" Tag.elem_match(child_tags: {name: 'sub_tag_1'}) # Searches for a child Tag in which one child Tag tame is "sub_sub_tag_1" root.child_tags.elem_match(child_tags: {name: 'sub_sub_tag_1'})
Para obtener más información sobre las asociaciones, consulte las guías de Asociaciones referenciadas y Asociaciones integradas.
Consulta por Valor _id
Mongoid proporciona el método find, que te permite consultar documentos por sus valores _id.
El siguiente ejemplo utiliza el método find para hacer coincidir un documento con el valor especificado en el campo _id:
Band.find('6725342d4cb3e161059f91d7')
Nota
Conversión de tipo
Cuando pasas un valor de ID al método find, el método lo convierte al tipo de datos declarado para el campo _id en el modelo. Por defecto, el campo _id se define como un tipo BSON::ObjectId.
El ejemplo anterior es equivalente al siguiente código, que pasa una instancia de BSON::ObjectId como argumento a find:
Band.find(BSON::ObjectId.from_string('5f0e41d92c97a64a26aabd10'))
Si utilizas el driver Ruby para realizar una query en el campo _id, find no realiza la conversión de tipos de forma interna.
El método find acepta múltiples argumentos, o un arreglo de argumentos. Mongoid interpreta cada argumento o elemento de arreglo como un valor _id y devuelve documentos con todos los valores especificados de _id en un arreglo, como se muestra en el siguiente ejemplo:
# Equivalent ways to match multiple documents Band.find('5f0e41d92c97a64a26aabd10', '5f0e41b02c97a64a26aabd0e') Band.find(['5f0e41d92c97a64a26aabd10', '5f0e41b02c97a64a26aabd0e'])
El método find exhibe el siguiente comportamiento:
Si proporciona el mismo valor de
_idmás de una vez, Mongoid solo devuelve un documento, si existe uno.Mongoid no devuelve documentos de manera ordenada. Los documentos podrían devolverse en un orden diferente al de los valores de
_idproporcionados.Si alguno de los valores de
_idno se encuentra en la base de datos, el resultado depende del valor de la opción de configuraciónraise_not_found_error.Si configuras la opción
raise_not_found_errorentrue,findgenera un errorMongoid::Errors::DocumentNotFoundsi no se encuentran algunos de los valores_id.Si configuras la opción
raise_not_found_errorafalsey haces una query por un solo valor de_id,finddevuelvenilsi Mongoid no encuentra un documento correspondiente. Si pasas varios valores de_idy alguno o todos no coinciden, el valor de retorno será un arreglo con cualquier documento que coincida o un arreglo vacío si ningún documento coincide.
encontrar Variaciones
Esta sección describe métodos que son similares al método find descrito en la sección anterior.
Puedes usar el método find_by para recuperar documentos basados en los criterios proporcionados. Si no se encuentran documentos, se genera un error o se retorna nil dependiendo de cómo se configure la opción raise_not_found_error.
El siguiente código demuestra cómo usar el método find_by:
# Simple equality query Band.find_by(name: "Photek") # Performs an action on each returned result Band.find_by(name: "Tool") do |band| band.fans += 1 end
Puedes utilizar el método find_or_create_by para recuperar documentos según los criterios proporcionados. Si no se encuentran documentos, se crea y se devuelve una instancia que se guarda en MongoDB.
El siguiente código demuestra cómo usar el método find_or_create_by:
# If no matches, creates a Band with just the "name" field Band.find_or_create_by(name: "Photek") # If no matches, creates a Band with just the "name" field because the # query condition is not a literal Band.where(:likes.gt => 10).find_or_create_by(name: "Photek") # Creates a Band in which the name is Aerosmith because there is no # document in which "name" is Photek and Aerosmith at the same time Band.where(name: "Photek").find_or_create_by(name: "Aerosmith")
Se puede utilizar el método find_or_initialize_by para recuperar documentos basados en los criterios proporcionados. Si no se encuentran documentos, se devuelve uno nuevo, sin persistirlo en MongoDB. Use la misma sintaxis para find_or_initialize_by que se utiliza para el método find_or_create_by.
Expresiones regulares
Mongoid permite query documentos usando expresiones regulares en los criterios de filtro.
El siguiente código crea un modelo de muestra de Band:
Band.create!(name: 'Tame Impala', description: "Tame\nImpala is an American band")
Puedes realizar búsquedas utilizando expresiones regulares de Ruby, como se muestra en el siguiente código:
# Matches documents in which the "name" field includes the string "impala" Band.where(name: /impala/i) # => Returns sample document
También puedes realizar queries utilizando la sintaxis de Expresión Regular Compatible con Perl (PCRE) y objetos BSON::Regexp::Raw:
# Matches "description" values that start exactly with "Impala" Band.where(description: /\AImpala/) # => nil # Matches "description" values that start exactly with "Impala" Band.where(description: BSON::Regexp::Raw.new('^Impala')) # => nil # Matches "description" values that start exactly with "Impala" with # the multiline option Band.where(description: BSON::Regexp::Raw.new('^Impala', 'm')) # => Returns sample document
Query Conversions de tipo de campo
Al especificar una query en un campo definido en un modelo, si el campo tiene un tipo de datos especificado, Mongoid convierte el valor de la query basado en cómo está definido el campo.
Considera la siguiente definición de modelo Album que contiene un campo con valor Date, un campo con valor Timey un campo implícito con valor Object. El modelo también no define intencionadamente un campo llamado last_reviewed:
class Album include Mongoid::Document field :release_date, type: Date field :last_commented, type: Time field :last_purchased end
Puede query los campos release_date y last_commented utilizando los valores Date y Time, como se muestra en el siguiente código:
Album.where(release_date: Date.today) # Interpreted query: # {"release_date"=>2024-11-05 00:00:00 UTC} Album.where(last_commented: Time.now) # Interpreted query: # {"last_commented"=>2024-11-04 17:20:47.329472 UTC}
Sin embargo, si realizas una query utilizando solo valores de Date en campos definidos como otros tipos, las consultas generadas muestran el comportamiento de conversión por defecto, como se muestra en el siguiente ejemplo:
Album.where(last_commented: Date.today) # Interpreted query: # {"last_commented"=>Mon, 04 Nov 2024 00:00:00.000000000 EST -05:00} Album.where(last_purchased: Date.today) # Interpreted query: # {"last_purchased"=>"2024-11-04"} Album.where(last_reviewed: Date.today) # Interpreted query: # {"last_reviewed"=>2024-11-04 00:00:00 UTC}
En el ejemplo anterior, las siguientes conversiones aplican:
Al utilizar un valor
Datepara query el campolast_commentedcon valorTime, Mongoid interpreta que la fecha está en hora local y aplica la zona horaria configurada.Al consultar el campo
last_purchased, que no tiene un tipo explícito, la fecha se utiliza sin modificarla en la query creada.Al realizar una consulta en el campo no definido
last_reviewed, Mongoid interpreta que elDateestá en UTC y lo convierte a una hora, coincidiendo con el comportamiento de consultar un campo con un valorDate, comorelease_date.
Métodos de query adicionales
Esta sección describe más métodos de query que puedes usar en Mongoid.
Contabilizar documentos
Puede usar los métodos count y estimated_count para contar la cantidad de documentos en una colección.
Puedes contar el número de documentos que coinciden con criterios de filtro usando el método count:
# Counts all documents in collection Band.count # Counts documents that match criteria Band.where(country: 'England').count
Tip
Métodos de longitud y tamaño
También puedes utilizar los métodos length o size para contar documentos. Estos métodos guardan en caché las siguientes llamadas a la base de datos, lo que podría mejorar el rendimiento.
Puedes obtener un número aproximado de documentos en la colección desde los metadatos de la colección utilizando el método estimated_count:
Band.estimated_count
El método estimated_count no acepta condiciones de query, incluidas las condiciones establecidas por un scope en el modelo. Si está llamando este método en un modelo con un alcance por defecto, debe llamar primero al método unscoped para desactivar dicho alcance.
Métodos ordinales
Los métodos descritos en la siguiente lista permiten seleccionar un resultado específico de la lista de documentos devueltos según su posición.
firstDevuelve el primer documento coincidente. Puede obtener los primerosndocumentos pasando un parámetro con valor entero. Este método utiliza automáticamente una ordenación en el campo_id. Consulte las líneas 1-8 en el siguiente código para ver ejemplos.lastDevuelve el último documento coincidente. Puede obtener los últimosndocumentos pasando un parámetro entero. Este método utiliza automáticamente una ordenación en el campo_id. Consulta la línea 11 en el siguiente código para un ejemplo.first_or_createDevuelve el primer documento que coincida. Si no hay ningún documento que coincida, crea y devuelve uno recién guardado.first_or_initializeDevuelve el primer documento coincidente. Si ningún documento coincide, devuelve uno nuevo.second: Retorna el segundo documento coincidente. Utiliza automáticamente una ordenación en el campo_id.third: Devuelve el tercer documento coincidente. Utiliza automáticamente una ordenación en el campo_id.fourth: Devuelve el cuarto documento coincidente. Utiliza automáticamente una ordenación en el campo_id.fifthDevuelve el quinto documento de coincidencia. Utiliza automáticamente una ordenación en el campo_id.second_to_lastDevuelve el penúltimo documento coincidente. Utiliza automáticamente un orden en el campo_id. Consulte la línea 14 en el siguiente código para ver un ejemplo.third_to_last: Devuelve el tercer documento coincidente antes del último. Utiliza automáticamente una ordenación en el campo_id.
El siguiente código demuestra cómo utilizar algunos métodos descritos en la lista anterior:
1 # Returns the first document in the collection 2 Band.first 3 4 # Returns the first matching document 5 Band.where(founded: {'$gt' => 1980}).first 6 7 # Returns the first two matching documents 8 Band.first(2) 9 10 # Returns the last matching document 11 Band.where(founded: {'$gt' => 1980}).last 12 13 # Returns the second to last document 14 Band.second_to_last
Tip
Generación de errores
Cada método descrito en esta sección tiene una variante que lleva el sufijo ! y que devuelve un error si Mongoid no coincide con ningún documento. Por ejemplo, para implementar la gestión de errores en tu aplicación cuando tu query no arroje resultados, utiliza el método first! en lugar de first.
Valores de campo de la encuesta
Para inspeccionar los valores de los campos especificados de los documentos en una colección, puedes usar los siguientes métodos:
distinct: Obtiene una lista de valores distintos para un campo único. Consulta las líneas 1-7 en el siguiente código para ver ejemplos.pick: Obtiene los valores de un documento para los campos proporcionados. Devuelvenilpara campos no establecidos y para campos inexistentes. Consulte la línea 10 en el siguiente código para ver un ejemplo.pluckObtiene todos los valores para el campo proporcionado. Devuelvenilpara los campos no establecidos y para los campos inexistentes. Vea la línea 13 en el siguiente código como ejemplo.tally: Obtiene un mapeo de valores a recuentos para el campo especificado. Consulta la línea 16 en el siguiente código como ejemplo.
Los métodos anteriores aceptan nombres de campos referenciados mediante la notación de puntos, lo que permite referenciar campos en asociaciones anidadas. También respetan los alias de campo, incluidos los definidos en documentos incrustados.
El siguiente código demuestra cómo utilizar estos métodos:
1 Band.distinct(:name) 2 # Example output: "Ghost Mountain" "Hello Goodbye" "She Said" 3 4 Band.where(:members.gt => 2).distinct(:name) 5 # Example output: "Arctic Monkeys" "The Smiths" 6 7 Band.distinct('tours.city') 8 # Example output: "London" "Sydney" "Amsterdam" 9 10 Band.all.pick(:name) 11 # Example output: "The Smiths" 12 13 Band.all.pluck(:country) 14 # Example output: "England" "Spain" "England" "Japan" 15 16 Band.all.tally(:country) 17 # Example output: ["England",2] ["Italy",3]
Misceláneo
La siguiente lista describe métodos de Mongoid que no encajan en otra categoría:
each: Itera sobre todos los documentos coincidentes.
# Print each matching document "name" to console Band.where(:members.gt => 1).each do |band| p band.name end
exists?: Determinar si existen documentos coincidentes, devolviendotruesi se encuentra al menos un documento coincidente.
# Checks existence of any document Band.exists? # Checks existence based on query Band.where(name: "Le Tigre").exists? Band.exists?(name: "Le Tigre") # Checks existence based on "_id" value Band.exists?('6320d96a3282a48cfce9e72c') # Always returns false Band.exists?(false) Band.exists?(nil)
Información Adicional
Para aprender cómo modificar la forma en que Mongoid te entrega resultados, consulta Modificar resultados de query.
Para obtener más información sobre cómo definir dimensiones en tus modelos, consulta Definición de ámbitos.
Para aprender sobre métodos que puede encadenar a las consultas para conservar datos, consulte Conservar datos de las consultas.
Para aprender sobre la funcionalidad de caché de querys, consulta Caché de querys.
Para aprender a realizar consultas asíncronas, consulte Consultas asíncronas.