Definição
$Use the positional
$operator to identify an element in an array to update without explicitly specifying the position of the element in the array.Observação
Desambiguação
Para projetar ou retornar um elemento de array de uma operação de leitura, consulte o operador de projeção
$.Para atualizar todos os elementos em uma array, consulte o operador posicional
$[].Para atualizar todos os elementos que correspondem a uma condição ou condições de filtro de array, consulte o operador posicional filtrado em vez de
$[<identifier>].
Compatibilidade
Você pode utilizar o operador posicional $ para sistemas hospedados nos seguintes ambientes:
- MongoDB Atlas: The fully managed service for MongoDB deployments in the cloud
MongoDB Enterprise: a versão autogerenciada e baseada em assinatura do MongoDB
MongoDB Community: uma versão com código disponível, de uso gratuito e autogerenciada do MongoDB
Sintaxe
The positional $ operator has the form:
{ "<array>.$" : value }
Quando você usa operações de atualização, como db.collection.updateOne() e db.collection.findAndModify(), ambas as condições a seguir devem ser verdadeiras:
The positional
$operator acts as a placeholder for the first element that matches thequery document.o campo
arraydeve aparecer como parte doquery document.
Por exemplo:
db.collection.updateOne( { <array>: value ... }, { <update operator>: { "<array>.$" : value } } )
Comportamento
A partir do MongoDB 5.0, os operadores de atualização processam campos de documento com nomes baseados em cadeia de caracteres em ordem lexicográfica. Os campos com nomes numéricos são processados em ordem numérica. Consulte Atualizar Comportamento de Operadores para detalhes.
upsert
Não use o operador $ em operações upsert. Se a query de atualização não corresponder a nenhum documento existente, o upsert falhará porque o operador $ exige um elemento de array correspondente.
Arrays agrupadas
You cannot use the positional $ operator for queries that traverse more than one array, such as queries that traverse arrays nested within other arrays, because the replacement for the $ placeholder is a single value.
Desconfigura
When you use the positional $ operator with the $unset operator, the positional operator does not remove the matching element from the array. Instead, it sets the element to null.
Negações
Se a query corresponder à array utilizando um operador de negação, como $ne, $not ou $nin, então você não poderá utilizar o operador posicional para atualizar valores desta array.
Você pode usar o operador posicional se a parte negada da query estiver dentro de uma expressão $elemMatch.
Várias correspondências de array
The positional $ update operator behaves ambiguously when you filter on multiple array fields.
When the server executes an update method, it first runs a query to determine which documents to update. If the update filters documents on multiple array fields, the positional $ update operator might not update the correct position in the array.
Para obter mais informações, consulte o exemplo.
Exemplos
Atualizar valores em uma array
Cria a coleção students com os seguintes documentos:
db.students.insertMany( [ { "_id" : 1, "grades" : [ 85, 80, 80 ] }, { "_id" : 2, "grades" : [ 88, 90, 92 ] }, { "_id" : 3, "grades" : [ 85, 100, 90 ] } ] )
To update the first element whose value is 80 to 82 in the in the grades array, use the positional $ operator if you do not know the position of the element in the array:
Importante
Você deve incluir o campo de array como parte do documento query.
db.students.updateOne( { _id: 1, grades: 80 }, { $set: { "grades.$" : 82 } } )
The positional $ operator acts as a placeholder for the first match of the update query document.
Após a operação, a coleção students contém os seguintes documentos:
{ "_id" : 1, "grades" : [ 85, 82, 80 ] } { "_id" : 2, "grades" : [ 88, 90, 92 ] } { "_id" : 3, "grades" : [ 85, 100, 90 ] }
Atualizar documentos em uma array
The positional $ operator allows updates to arrays that have embedded documents. Use the positional $ operator to access fields in embedded documents. Use dot notation on the $ operator.
db.collection.updateOne( { <query selector> }, { <update operator>: { "array.$.field" : value } } )
Considere o seguinte documento na collection students cujo valor do elemento grades é uma array de documentos incorporados:
{ _id: 4, grades: [ { grade: 80, mean: 75, std: 8 }, { grade: 85, mean: 90, std: 5 }, { grade: 85, mean: 85, std: 8 } ] }
Use the positional $ operator to update the std field of the first array element that matches the grade equal to 85 condition:
Importante
Você deve incluir o campo de array como parte do documento query.
db.students.updateOne( { _id: 4, "grades.grade": 85 }, { $set: { "grades.$.std" : 6 } } )
Após a operação, o documento tem os seguintes valores atualizados:
{ "_id" : 4, "grades" : [ { "grade" : 80, "mean" : 75, "std" : 8 }, { "grade" : 85, "mean" : 90, "std" : 6 }, { "grade" : 85, "mean" : 85, "std" : 8 } ] }
Atualizar documentos incorporados usando correspondências de vários campos
Use the $ operator to update the first array element that matches multiple query criteria specified with the $elemMatch operator.
Considere o seguinte documento na collection students cujo valor de campo grades é uma array de documentos incorporados:
{ _id: 5, grades: [ { grade: 80, mean: 75, std: 8 }, { grade: 85, mean: 90, std: 5 }, { grade: 90, mean: 85, std: 3 } ] }
In the following example, the $ operator updates the value of the std field in the first embedded document that has a grade field with a value less than or equal to 90 and a mean field with a value greater than 80:
db.students.updateOne( { _id: 5, grades: { $elemMatch: { grade: { $lte: 90 }, mean: { $gt: 80 } } } }, { $set: { "grades.$.std" : 6 } } )
Esta operação atualiza o primeiro documento incorporado que corresponde aos critérios, ou seja, o segundo documento incorporado na array:
{ _id: 5, grades: [ { grade: 80, mean: 75, std: 8 }, { grade: 85, mean: 90, std: 6 }, { grade: 90, mean: 85, std: 3 } ] }
Atualizar com várias correspondências de array
The positional $ update operator behaves ambiguously when the query has multiple array fields to filter documents in the collection.
Considere um documento da collection students_deans_list, que contém arrays de informações dos alunos:
db.students_deans_list.insertMany( [ { _id: 8, activity_ids: [ 1, 2 ], grades: [ 90, 95 ], deans_list: [ 2021, 2020 ] } ] )
No exemplo seguinte, o usuário tenta modificar o campo deans_list. O exemplo filtra documentos usando os campos activity_ids, deans_list e grades e atualiza o valor 2021 no campo deans_list para 2022:
db.students_deans_list.updateOne( { activity_ids: 1, grades: 95, deans_list: 2021 }, { $set: { "deans_list.$": 2022 } } )
When the server executes the preceding updateOne method, it filters the available documents using values in the supplied array fields. Although the deans_list field is used in the filter, it is not the field used by the positional $ update operator to determine which position in the array to update:
db.students_deans_list.find( { _id: 8 } )
Saída de exemplo:
{ _id: 8, activity_ids: [ 1, 2 ], grades: [ 90, 95 ], deans_list: [ 2021, 2022 ] }
The updateOne method matched the deans_list field on 2021, but the positional $ update operator instead changed the 2020 value to 2022.
Para evitar resultados inesperados ao fazer a correspondência em várias arrays, use o operador posicional filtrado $[<identifier>].
Saiba mais
For examples that use the $ operator to update arrays, see Update Array Elements with MQL Positional Operators.