Página inicial do Docs → Desenvolver aplicações → Manual do MongoDB
$elemMatch (projeção)
Nesta página
Dica
Veja também:
Definição
$elemMatch
O operador
$elemMatch
limita o conteúdo de um campo<array>
dos resultados da query para conter apenas o primeiro elemento que corresponda à condição$elemMatch
.
Considerações de uso
Elemento retornado
Tanto o operador $
quanto o operador $elemMatch
projetam o primeiro elemento correspondente de uma array com base em uma condição.
O operador $
projeta o primeiro elemento de array correspondente de cada documento em uma collection com base em alguma condição da declaração de query.
O operador de projeção $elemMatch
usa um argumento de condição explícita. Isso permite que você projete com base em uma condição que não esteja na query ou, se precisar projetar, com base em vários campos nos documentos incorporados da array. Consulte Limitações de campos de array para obter um exemplo.
Ordem do campo
Independentemente da ordenação dos campos no documento, a projeção $elemMatch
de um campo existente retorna o campo após as outras inclusões de campo existentes.
Por exemplo, considere uma collection players
com o seguinte 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") } )
A projeção a seguir retorna o campo games
após os outros campos existentes incluídos na projeção, mesmo que, no documento, o campo esteja listado antes dos campos joined
e lastLogin
:
db.players.find( {}, { games: { $elemMatch: { score: { $gt: 5 } } }, joined: 1, lastLogin: 1 } )
Ou seja, a operação retorna o seguinte documento:
{ "_id" : ObjectId("5edef64a1c099fff6b033977"), "joined" : ISODate("2020-01-01T00:00:00Z"), "lastLogin" : ISODate("2020-05-01T00:00:00Z"), "games" : [ { "game" : "abc", "score" : 8 } ] }
Na versão 4.2 e anterior, a projeção $elemMatch
de um campo existente mantém a ordem no documento:
{ "_id" : ObjectId("5edef91e76ddff7d92f118e1"), "games" : [ { "game" : "abc", "score" : 8 } ], "joined" : ISODate("2020-01-01T00:00:00Z"), "lastLogin" : ISODate("2020-05-01T00:00:00Z") }
Restrições
As operações
db.collection.find()
em visualizações não são compatíveis com o operador de projeção$elemMatch
.Você não pode especificar uma expressão de query
$text
em um$elemMatch
.
Exemplos
Os exemplos no operador de projeção $elemMatch
pressupõem uma collection schools
com os seguintes 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 }, ] }
Pesquisa de CEP
A seguinte operação find()
faz uma query de todos os documentos onde o valor do campo zipcode
é 63109
. A projeção $elemMatch
retorna somente o primeiro elemento correspondente da array students
em que o campo school
tem um valor de 102
:
db.schools.find( { zipcode: "63109" }, { students: { $elemMatch: { school: 102 } } } )
A operação retorna os seguintes documentos que têm zipcode
igual a 63109
e projeta a 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 o documento com
_id
igual a1
, a arraystudents
contém vários elementos com o camposchool
igual a102
. No entanto, a projeção$elemMatch
retorna somente o primeiro elemento correspondente da array.O documento com
_id
igual a3
não contém o campostudents
no resultado, pois nenhum elemento em sua arraystudents
correspondeu à condição$elemMatch
.
$elemMatch
com vários campos
A projeção $elemMatch
pode especificar critérios em vários campos:
A seguinte operação find()
faz uma query de todos os documentos onde o valor do campo zipcode
é 63109
. A projeção inclui o primeiro elemento correspondente da array students
onde o campo school
tem um valor de 102
e o campo age
é maior que 10
:
db.schools.find( { zipcode: "63109" }, { students: { $elemMatch: { school: 102, age: { $gt: 10} } } } )
A operação retorna os três documentos que têm zipcode
igual a 63109
:
{ "_id" : 1, "students" : [ { "name" : "jess", "school" : 102, "age" : 11 } ] } { "_id" : 3 } { "_id" : 4, "students" : [ { "name" : "ruth", "school" : 102, "age" : 16 } ] }
O documento com _id
igual a 3
não contém o campo students
já que nenhum elemento de array corresponde aos critérios $elemMatch
.
O argumento para $elemMatch
corresponde aos elementos da array que $elemMatch
está projetando. Se você especificar uma igualdade com um nome de campo para $elemMatch
, ele tentará corresponder a objetos dentro da array. Por exemplo, $elemMatch
tenta combinar objetos, em vez de valores escalares, dentro da array para o seguinte na projeção:
db.schools.find( { zipcode: "63109" }, { athletics: { $elemMatch: { athletics: "basketball" } } })
Para corresponder valores escalares, use o operador de igualdade junto com o valor escalar que você deseja corresponder ({$eq: <scalar value>}
). Por exemplo, a seguinte operação find()
faz uma query de todos os documentos onde o valor do campo zipcode
é 63109
. A projeção inclui o elemento correspondente da array athletics
onde o valor é basketball
:
db.schools.find( { zipcode: "63109" }, { athletics: { $elemMatch: { $eq: "basketball" } } })
A operação retorna os três documentos que têm zipcode
igual a 63109
:
[ { _id : 1 }, { _id: 3, athletics: [ 'basketball' ] }, { _id : 4 } ]
O documento com _id
igual a 3
é o único documento que corresponde aos critérios $elemMatch
.
Dica
Veja também:
$ (projection)
operador, operador