Definição
$Utilize o operador posicional
$para identificar 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>].
Compatibilidade
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
Sintaxe
O operador posicional $ tem o formato:
{ "<array>.$" : value }
Quando você usa operações de atualização, como e, ambas as condições a seguir devem ser db.collection.updateOne() db.collection.findAndModify()verdadeiras:
O operador posicional atua como um
$espaço reservado para o primeiro elemento que correspondequery documenta.O
arraycampo deve aparecer como partequery documentdo.
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
Você não pode utilizar o operador posicional 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.
Desconfigura
Quando você usa o operador posicional $ com o operador, o operador posicional não remove o elemento correspondente da array. Em vez disso, ela define o $unset elemento null como.
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 $elemMatch expressão.
Várias correspondências de array
O $ operador de atualização posicional se comporta de forma ambígua quando você filtra vários campos de array.
Quando o servidor executa um método de atualização, ele primeiro executa uma query para determinar quais documentos atualizar. Se a atualização filtrar documentos em vários campos de array, o $ operador de atualização posicional poderá não atualizar a posição correta na 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 ] } ] )
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 ] }
Atualizar documentos em uma array
O operador posicional$permite atualizações em arrays que tenham documentos incorporados. Use o operador posicional$para acessar campos em documentos incorporados. Use 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 } ] }
Atualizar documentos incorporados usando correspondências de vários campos
Utilize o operador para atualizar o primeiro elemento de array $ $elemMatch que corresponde a vários critérios de query especificados com o operador.
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 a seguir, o operador atualiza o valor $ do std campo no primeiro documento incorporado que tem um grade campo com um valor menor ou igual a 90 e um mean campo com valor superior 80 a:
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
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 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 } } )
Quando o servidor executa o updateOne método anterior, ele filtra os documentos disponíveis utilizando valores nos campos de array fornecidos. Embora o deans_list campo 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.
Saiba mais
Para exemplos que utilizam o operador $ para atualizar arrays, consulte Atualizar elementos de array em um documento com operadores posicionais MQL.