Menu Docs
Página inicial do Docs
/
Manual do MongoDB
/ / / /

$ (update)

Nesta página

  • Definição
  • Compatibilidade
  • Sintaxe
  • Comportamento
  • Exemplos
$

O operador posicional $ identifica um elemento em uma array para atualizar sem especificar explicitamente a posição do elemento na 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>].

Você pode utilizar o operador posicional $ para sistemas hospedados nos seguintes ambientes:

  • MongoDB Atlas: o serviço totalmente gerenciado para implantações do MongoDB na nuvem

  • 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

O operador posicional $ tem o formato:

{ "<array>.$" : value }

Quando usado com operações de atualização, por exemplo, db.collection.updateOne() e db.collection.findAndModify(),

  • O operador posicional $ atua como um placeholder para o primeiro elemento que corresponde a query document, e

  • o campo array deve aparecer como parte do query document.

Por exemplo:

db.collection.updateOne(
{ <array>: value ... },
{ <update operator>: { "<array>.$" : value } }
)

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.

Não use o operador posicional $ com operações upsert porque as inserções usarão $ como um nome de campo no documento inserido.

O operador posicional $ não pode ser usado para queries que atravessam mais de uma array, como queries que atravessam arrays agrupadas em outras arrays, porque a substituição do espaço reservado $ é um único valor

Quando usado com o operador $unset, o operador posicional $ não remove o elemento correspondente da array, mas o define como null.

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.

No entanto, se a parte negada da query estiver dentro de uma expressão $elemMatch, então você pode utilizar o operador posicional para atualizar este campo.

O operador de atualização posicional $ se comporta de forma ambígua ao filtrar vários campos de array.

Quando o servidor executa um método de atualização, ele primeiro executa uma query para determinar quais documentos você deseja atualizar. Se a atualização filtrar documentos em vários campos de array, a chamada subsequente para o operador de atualização posicional $ nem sempre atualizará a posição necessária no array.

Para obter mais informações, consulte o exemplo.

Crie uma collection 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 ] }
] )

Para atualizar o primeiro elemento cujo valor é 80 a 82 na array grades, utilize o operador posicional $ se você não souber a posição do elemento na array:

Importante

Você deve incluir o campo de array como parte do documento query.

db.students.updateOne(
{ _id: 1, grades: 80 },
{ $set: { "grades.$" : 82 } }
)

O operador posicional $ atua como um espaço reservado para a primeira correspondência da atualização do documento de consulta.

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 ] }

O operador posicional $ facilita as atualizações de arrays que contêm documentos incorporados. Use o operador posicional $ para acessar os campos nos documentos incorporados com a notação de ponto no operador $.

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 o operador posicional $ para atualizar o campo std do primeiro elemento de array que corresponda à condição grade igual a 85:

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 }
]
}

O operador $ pode atualizar o primeiro elemento de array que corresponda a vários critérios de query com o operador $elemMatch.

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 }
]
}

No exemplo abaixo, o operador $ atualiza o valor do campo std no primeiro documento incorporado que tem um campo grade com um valor menor ou igual a 90 e um campo mean com um valor maior que 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 }
]
}

O operador de atualização posicional $ se comporta de forma ambígua quando a query tem vários campos de array para filtrar documentos na coleção.

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 a seguir, o usuário tenta modificar o campo deans_list, filtrando documentos usando os campos activity_ids, deans_list e grades, e atualizando o valor de 2021 no campo deans_list para 2022:

db.students_deans_list.updateOne(
{ activity_ids: 1, grades: 95, deans_list: 2021 },
{ $set: { "deans_list.$": 2022 } }
)

Quando o servidor executa o método updateOne acima, ele filtra os documentos disponíveis utilizando valores nos campos de array fornecidos. Embora o campo deans_list seja usado no filtro, ele não é o campo usado pelo operador de atualização posicional $ para determinar qual posição na array atualizar:

db.students_deans_list.find( { _id: 8 } )

Saída de exemplo:

{
_id: 8,
activity_ids: [ 1, 2 ],
grades: [ 90, 95 ],
deans_list: [ 2021, 2022 ]
}

O método updateOne correspondeu ao campo deans_list em 2021, mas o operador de atualização posicional $ alterou o valor 2020 para 2022.

Para evitar resultados inesperados ao fazer a correspondência em várias arrays, use o operador posicional $[<identifier>] filtrado.

Dica

Veja também:

Voltar

arrays