$ (projeção)
Definição
$
O operador posicional
$
limita o conteúdo de um<array>
para retornar o primeiro elemento que corresponde à condição de consulta na array.Use
$
no documento defind()
projeção do método ou dofindOne()
método quando precisar apenas de um elemento de array específico em documentos selecionados.Consulte o operador de aggregation
$filter
para retornar uma array com apenas os elementos que correspondem à condição especificada.Observação
Desambiguação
Para especificar um elemento de array para atualizar, consulte o operador posicional $ para atualizações.
Considerações de uso
O operador $
e 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 coleção com base em alguma condição da declaração de query.
O operador de projeção $elemMatch
utiliza 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 campo de array para obter um exemplo.
As operações db.collection.find()
nas visualizações não são compatíveis com o operador de projeção $
.
Comportamento
Sintaxe
Para retornar o primeiro elemento da array que corresponde à condição de q especificada na array:
db.collection.find( { <array>: <condition> ... }, { "<array>.$": 1 } ) db.collection.find( { <array.field>: <condition> ...}, { "<array>.$": 1 } )
Você pode usar o operador $
para limitar um campo <array>
, que não aparece no documento de query. Nas versões anteriores do MongoDB, o campo <array>
que está sendo limitado deve aparecer no documento de query.
db.collection.find( { <someOtherArray>: <condition> ... }, { "<array>.$" : 1 } )
Importante
Para garantir o comportamento esperado, as arrays usadas no documento de query e o documento de projeção devem ter o mesmo comprimento. Se as arrays tiverem comprimentos diferentes, a operação poderá apresentar erros em determinados cenários.
Limitações do campo de array
O MongoDB exige o seguinte ao lidar com projeção sobre arrays:
Somente um operador posicional
$
pode aparecer no documento de projeção.Somente um campo de array deve aparecer no documento de query. Campos de array adicionais no documento de query podem levar a comportamento indefinido.
Por exemplo, a seguinte projeção pode levar a um comportamento indefinido:
db.collection.find( { <array>: <value>, <someOtherArray>: <value2> }, { "<array>.$": 1 } ) O documento de query deve conter apenas uma única condição no campo de array ao qual é aplicado. Várias condições podem se substituir internamente e levar a um comportamento indefinido.
Para especificar critérios em vários campos de documentos dentro dessa array, use o operador de query
$elemMatch
. A query a seguir retorna o primeiro documento dentro de uma arraygrades
que tem ummean
maior que 70 e umgrade
maior que 90.db.students.find( { grades: { $elemMatch: { mean: { $gt: 70 }, grade: { $gt:90 } } } }, { "grades.$": 1 } ) Você deve usar o operador
$elemMatch
se precisar de condições separadas para selecionar documentos e para escolher campos dentro desses documentos.
Ordenações e o operador posicional
Quando o método find()
inclui um sort()
, o método find()
aplica sort()
para ordenar os documentos correspondentes antes de aplicar o operador de projeção $
posicional.
Se um campo de array contiver vários documentos com o mesmo nome de campo e o método find()
incluir um sort()
nesse campo repetitivo, os documentos retornados poderão não refletir a ordem de classificação porque a ordenação foi aplicada aos elementos da array antes do operador de projeção $
.
Restrição de colocação do operador posicional
O operador de projeção $
só pode aparecer no final do caminho do campo, por exemplo "field.$"
ou "fieldA.fieldB.$"
.
Por exemplo, operação a seguir é inválida:
db.inventory.find( { }, { "instock.$.qty": 1 } )
Para resolver, remova o componente do caminho do campo que segue o operador de projeção $
.
Operador posicional $slice
e restrição
As projeções find
e findAndModify
não podem incluir a expressão de projeção $slice
como parte de uma expressão de projeção $
.
Por exemplo, operação a seguir é inválida:
db.inventory.find( { "instock.qty": { $gt: 25 } }, { "instock.$": { $slice: 1 } } )
Nas versões anteriores, o MongoDB retorna o primeiro elemento (instock.$
) na anterior instock
que corresponde à condição de query, ou seja, a projeção posicional "instock.$"
tem precedência e a $slice:1
não contém nenhum oplog. "instock.$": {
$slice: 1 }
não exclui nenhum outro campo do documento.
Exemplos
Projetar valores de array
Uma coleção students
contém os seguintes documentos:
{ "_id" : 1, "semester" : 1, "grades" : [ 70, 87, 90 ] } { "_id" : 2, "semester" : 1, "grades" : [ 90, 88, 92 ] } { "_id" : 3, "semester" : 1, "grades" : [ 85, 100, 90 ] } { "_id" : 4, "semester" : 2, "grades" : [ 79, 85, 80 ] } { "_id" : 5, "semester" : 2, "grades" : [ 88, 88, 92 ] } { "_id" : 6, "semester" : 2, "grades" : [ 95, 90, 96 ] }
Na consulta a seguir, a projeção { "grades.$": 1 }
retorna somente o primeiro elemento maior ou igual a 85
para o campo grades
.
db.students.find( { semester: 1, grades: { $gte: 85 } }, { "grades.$": 1 } )
A operação retorna os seguintes documentos:
{ "_id" : 1, "grades" : [ 87 ] } { "_id" : 2, "grades" : [ 90 ] } { "_id" : 3, "grades" : [ 85 ] }
Embora o campo de array grades
possa conter vários elementos maiores ou iguais a 85
, o operador de projeção $
retornará apenas o primeiro elemento correspondente da array.
Projetar documentos de array
Uma collection students
contém os seguintes documentos onde o campo grades
é uma array de documentos; cada documento contém os três nomes de campo grade
, mean
e std
:
{ "_id" : 7, semester: 3, "grades" : [ { grade: 80, mean: 75, std: 8 }, { grade: 85, mean: 90, std: 5 }, { grade: 90, mean: 85, std: 3 } ] } { "_id" : 8, semester: 3, "grades" : [ { grade: 92, mean: 88, std: 8 }, { grade: 78, mean: 90, std: 5 }, { grade: 88, mean: 85, std: 3 } ] }
Na query a seguir, a projeção { "grades.$": 1 }
retorna apenas o primeiro elemento com mean
maior que 70
para o campo grades
:
db.students.find( { "grades.mean": { $gt: 70 } }, { "grades.$": 1 } )
A operação retorna os seguintes documentos:
{ "_id" : 7, "grades" : [ { "grade" : 80, "mean" : 75, "std" : 8 } ] } { "_id" : 8, "grades" : [ { "grade" : 92, "mean" : 88, "std" : 8 } ] }