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 $elemMatch operan proyectando el primer elemento coincidente de un arreglo en función de 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 proyección $elemMatch 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 puede especificar un operador del 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 }, ], athletics: [ "swimming", "basketball", "football" ] }, { _id: 3, zipcode: "63109", students: [ { name: "ajax", school: 100, age: 7 }, { name: "achilles", school: 100, age: 8 }, ], athletics: [ "baseball", "basketball", "soccer" ] }, { _id: 4, zipcode: "63109", students: [ { name: "barney", school: 102, age: 7 }, { name: "ruth", school: 102, age: 16 }, ] }
Búsqueda por código postal
La operación devuelve los siguientes documentos que tienen un valor zipcode de "63109" y proyecta el array students usando $elemMatch: La operación devuelve los siguientes documentos que tienen un valor zipcode de "63109" y proyecta el array students usando $elemMatch:
[ { "_id": 1, "students": [ { "name": "john", "school": 102, "age": 10 } ] }, { "_id": 3 }, { "_id": 4, "students": [ { "name": "barney", "school": 102, "age": 7 } ] } ]
Para el documento con
_idigual a1, el arreglostudentscontiene varios elementos con el camposchooligual a102. Sin embargo, la proyección$elemMatchsolo devuelve el primer elemento correspondiente del arreglo.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 operación devuelve los tres documentos que tienen un valor zipcode igual a "63109": La operación devuelve los tres documentos que tienen un valor zipcode 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 campo students ya que ningún elemento del arreglo coincide con el criterio $elemMatch.
El argumento para $elemMatch se corresponde con los elementos del arreglo que $elemMatch está proyectando. Si se especifica una igualdad con un nombre de campo a $elemMatch, se intenta hacer coincidir objetos dentro del arreglo. Por ejemplo, $elemMatch intenta hacer coincidir objetos, en lugar de valores escalares, dentro del arreglo para lo siguiente en la proyección:
Los ejemplos precedentes devuelven los documentos que tienen un valor de zipcode de "63109", pero estos documentos sólo incluyen el campo _id porque la operación de proyección no encontró elementos coincidentes.
La operación devuelve los tres documentos que tienen el valor zipcode igual a "63109". Los documentos devueltos incluyen el campo _id y los elementos coincidentes del array athletics, si los hay. La operación devuelve los tres documentos que tienen el valor zipcode igual a "63109". Los documentos devueltos incluyen el campo _id y los elementos coincidentes del array athletics, si los hay.
[ { "_id": 1 }, { "_id": 3, "athletics": [ "basketball" ] }, { "_id": 4 } ]
El documento con _id igual a 3 es el único documento que cumple con los criterios $elemMatch.
Tip
$ (projection) operador