Definição
$Use o operador posicional para identificar um elemento em uma array a ser atualizado 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 db.collection.updateOne() e db.collection.findAndModify(), ambas as condições a seguir devem ser verdadeiras:
O operador posicional atua como um
$espaço reservado para o primeiro elemento que correspondequery documenta.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
Você não pode usar 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 expressão $elemMatch.
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 grades array, 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 query.
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 std campo do primeiro elemento de array que corresponda grade à 85 condição igual a:
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 o operador para atualizar o primeiro elemento de array $ $elemMatch que corresponda 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 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 } } )
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 updateOne método correspondeu ao deans_list campo 2021 em, mas o $ operador de atualização posicional alterou o 2020 valor 2022 para.
Para evitar resultados inesperados ao fazer a correspondência em várias arrays, use o operador posicional filtrado $[<identifier>].
Saiba mais
Para exemplos que usam o $ operador para atualizar arrays, consulte Atualizar elementos de array com operadores posicionais MQL .