Definición
$elemMatchEl operador
$elemMatchlimita el contenido de un campo<array>de los resultados de la query para contener solo el primer elemento que coincida con la condición de$elemMatch.
Consideraciones sobre el uso
Elemento devuelto
Tanto el operador $ como el operador $elemMatch proyectan el primer elemento coincidente de una matriz según una condición.
El operador $ proyecta el primer elemento de un arreglo coincidente de cada documento en una colección, según alguna condición de la instrucción de query.
El operador de proyección $elemMatch toma un argumento explícito de condición. Esto permite proyectar lo que no está presente en la query, o que puedas proyectar varios campos en los documentos incrustados del arreglo. Consulta Limitaciones de campos de arreglos para un ejemplo.
Orden de campos
Independientemente del orden de los campos en el documento, la $elemMatch proyección de un campo existente devuelve el campo después de las otras inclusiones de campos existentes.
Por ejemplo, considera una colección players con el siguiente documento:
db.players.insertOne( { name: "player1", games: [ { game: "abc", score: 8 }, { game: "xyz", score: 5 } ], joined: new Date("2020-01-01"), lastLogin: new Date("2020-05-01") } )
La siguiente proyección retorna el campo games después de los otros campos existentes incluidos en la proyección, aunque en el documento, el campo está listado antes de los campos joined y lastLogin:
db.players.find( {}, { games: { $elemMatch: { score: { $gt: 5 } } }, joined: 1, lastLogin: 1 } )
Es decir, la operación devuelve el siguiente documento:
{ "_id" : ObjectId("5edef64a1c099fff6b033977"), "joined" : ISODate("2020-01-01T00:00:00Z"), "lastLogin" : ISODate("2020-05-01T00:00:00Z"), "games" : [ { "game" : "abc", "score" : 8 } ] }
Restricciones
Las operaciones
db.collection.find()en vistas no con compatibles con el operador de proyección$elemMatch.No se puede especificar una expresión de query
$texten un$elemMatch.
Ejemplos
Los ejemplos sobre el operador de proyección $elemMatch asumen una colección schools con los siguientes documentos:
{ _id: 1, zipcode: "63109", students: [ { name: "john", school: 102, age: 10 }, { name: "jess", school: 102, age: 11 }, { name: "jeff", school: 108, age: 15 } ] } { _id: 2, zipcode: "63110", students: [ { name: "ajax", school: 100, age: 7 }, { name: "achilles", school: 100, age: 8 }, ] } { _id: 3, zipcode: "63109", students: [ { name: "ajax", school: 100, age: 7 }, { name: "achilles", school: 100, age: 8 }, ] } { _id: 4, zipcode: "63109", students: [ { name: "barney", school: 102, age: 7 }, { name: "ruth", school: 102, age: 16 }, ] }
Búsqueda por código postal
La siguiente operación find() query para todos los documentos donde el valor del campo zipcode es 63109. La proyección $elemMatch devuelve solo el primer elemento coincidente del arreglo students donde el campo school tiene un valor de 102:
db.schools.find( { zipcode: "63109" }, { students: { $elemMatch: { school: 102 } } } )
La operación devuelve los siguientes documentos que tienen zipcode igual a 63109 y proyecta la students matriz $elemMatch usando:
{ "_id" : 1, "students" : [ { "name" : "john", "school" : 102, "age" : 10 } ] } { "_id" : 3 } { "_id" : 4, "students" : [ { "name" : "barney", "school" : 102, "age" : 7 } ] }
Para el documento con
_idigual1a, lastudentsmatriz contiene varios elementos con elschoolcampo igual102a. Sin embargo, la proyección solo devuelve el primer elemento$elemMatchcoincidente de la matriz.El documento con
_idigual a3no contiene el campostudentsen el resultado ya que ningún elemento en su arreglostudentscoincidió con la condición$elemMatch.
$elemMatch con varios campos
La proyección $elemMatch puede especificar criterios en varios campos:
La siguiente operación consulta todos los documentos cuyo valor find() del zipcode campo 63109 sea. La proyección incluye el primer elemento coincidente de la students matriz donde el valor del school campo sea 102 y el age valor del campo sea mayor 10 que:
db.schools.find( { zipcode: "63109" }, { students: { $elemMatch: { school: 102, age: { $gt: 10} } } } )
La operación devuelve tres documentos en los que zipcode es igual a 63109:
{ "_id" : 1, "students" : [ { "name" : "jess", "school" : 102, "age" : 11 } ] } { "_id" : 3 } { "_id" : 4, "students" : [ { "name" : "ruth", "school" : 102, "age" : 16 } ] }
El documento con _id igual a 3 no contiene el students campo ya que ningún elemento de la matriz coincide con los $elemMatch criterios.
Tip
$ (projection) operador