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

$[<identifier>]

Nesta página

  • Definição
  • Comportamento
  • Restrições
  • upsert
  • Arrays agrupadas
  • Exemplos
  • Atualizar todos os elementos de array que correspondem arrayFilters
  • Atualizar todos os documentos que correspondem a arrayFilters em uma array
  • Atualizar todos os elementos de array que correspondem a várias condições
  • Atualizar elementos de array usando um operador de negação
  • Atualizar matrizes agrupadas em conjunto com $[]
$[<identifier>]

O operador posicional filtrado $[<identifier>] identifica os elementos de array que correspondem às condições arrayFilters para uma operação de atualização, por exemplo, db.collection.updateMany() e db.collection.findAndModify().

Usado em conjunto com a opção arrayFilters, o operador $[<identifier>] tem o seguinte formato:

{ <update operator>: { "<array>.$[<identifier>]" : value } },
{ arrayFilters: [ { <identifier>: <condition> } ] }

Use em conjunto com a opção arrayFilters para atualizar todos os elementos que correspondam às condições 11ArrayFilters`` no documento ou nos documentos que correspondam às condições da query. Por exemplo:

db.collection.updateMany(
{ <query conditions> },
{ <update operator>: { "<array>.$[<identifier>]" : value } },
{ arrayFilters: [ { <identifier>: <condition> } ] }
)

Observação

O <identifier> deve começar com uma letra minúscula e conter apenas caracteres alfanuméricos.

Para obter um exemplo, consulte Atualizar todos os elementos de array que correspondem a arrayFilters.

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.

A opção arrayFilters não pode incluir os seguintes operadores de query:

  • $expr

  • $text

  • $where

Se uma operação upsert resultar em uma inserção, query deverá incluir uma correspondência exata de igualdade no campo de array para que seja possível usar $[<identifier>] na declaração de atualização.

Por exemplo, a seguinte operação de upsert, que utiliza $[<identifier>] no documento de atualização, especifica uma condição exata de correspondência de igualdade no campo de array:

db.collection.updateOne(
{ myArray: [ 0, 1 ] },
{ $set: { "myArray.$[element]": 2 } },
{ arrayFilters: [ { element: 0 } ], upsert: true }
)

Se tal documento não existir, a operação resultará na inserção de um documento semelhante ao seguinte:

{ "_id" : ObjectId(...), "myArray" : [ 2, 1 ] }

Se a operação upsert não incluísse uma correspondência de igualdade exata e nenhum documento correspondente fosse encontrado para atualizar, a operação upsert apresentaria erro. Por exemplo, as seguintes operações apresentariam erro se nenhum documento correspondente fosse encontrado para atualização:

db.array.updateOne(
{ },
{ $set: { "myArray.$[element]": 10 } },
{ arrayFilters: [ { element: 9 } ], upsert: true }
)

A operação retornaria um erro que se assemelha ao seguinte:

MongoServerError: The path 'myArray' must exist in the document in order to apply array updates.

O operador posicional $[<identifier>] filtrado pode ser usado para queries que atravessam mais de uma array e arrays agrupadas.

Para obter um exemplo, consulte Atualizar arrays agrupadas em conjunto com $[].

Crie a coleção students:

db.students.insertMany( [
{ "_id" : 1, "grades" : [ 95, 92, 90 ] },
{ "_id" : 2, "grades" : [ 98, 100, 102 ] },
{ "_id" : 3, "grades" : [ 95, 110, 100 ] }
] )

Para atualizar todos os elementos que são maiores ou iguais a 100 no array grades, utilize o operador posicional filtrado $[<identifier>] com o arrayFilters:

db.students.updateMany(
{ },
{ $set: { "grades.$[element]" : 100 } },
{ arrayFilters: [ { "element": { $gte: 100 } } ] }
)

O operador posicional $[<identifier>] atua como um espaço reservado para todos os elementos no campo de array que correspondem às condições especificadas em arrayFilters.

Após a operação, a coleção students contém os seguintes documentos:

{ "_id" : 1, "grades" : [ 95, 92, 90 ] }
{ "_id" : 2, "grades" : [ 98, 100, 100 ] }
{ "_id" : 3, "grades" : [ 95, 100, 100 ] }

O operador $[<identifier>] facilita as atualizações de arrays que contêm documentos incorporados. Para acessar os campos nos documentos incorporados, use a notação de ponto com $[<identifier>].

db.collection.updateMany(
{ <query selector> },
{ <update operator>: { "array.$[<identifier>].field" : value } },
{ arrayFilters: [ { <identifier>: <condition> } } ] }
)

Crie a coleção students2:

db.students2.insertMany( [
{
"_id" : 1,
"grades" : [
{ "grade" : 80, "mean" : 75, "std" : 6 },
{ "grade" : 85, "mean" : 90, "std" : 4 },
{ "grade" : 85, "mean" : 85, "std" : 6 }
]
},
{
"_id" : 2,
"grades" : [
{ "grade" : 90, "mean" : 75, "std" : 6 },
{ "grade" : 87, "mean" : 90, "std" : 3 },
{ "grade" : 85, "mean" : 85, "std" : 4 }
]
}
] )

Para modificar o valor do campo mean para todos os elementos na array grades em que a nota é maior ou igual a 85, use o operador posicional $[<identifier>] e arrayFilters:

db.students2.updateMany(
{ },
{ $set: { "grades.$[elem].mean" : 100 } },
{ arrayFilters: [ { "elem.grade": { $gte: 85 } } ] }
)

Após a operação, a coleção conta com os seguintes documentos:

{
"_id" : 1,
"grades" : [
{ "grade" : 80, "mean" : 75, "std" : 6 },
{ "grade" : 85, "mean" : 100, "std" : 4 },
{ "grade" : 85, "mean" : 100, "std" : 6 }
]
}
{
"_id" : 2,
"grades" : [
{ "grade" : 90, "mean" : 100, "std" : 6 },
{ "grade" : 87, "mean" : 100, "std" : 3 },
{ "grade" : 85, "mean" : 100, "std" : 4 }
]
}

Crie a coleção students3:

db.students3.insertMany( [
{
"_id" : 1,
"grades" : [
{ "grade" : 80, "mean" : 75, "std" : 6 },
{ "grade" : 85, "mean" : 100, "std" : 4 },
{ "grade" : 85, "mean" : 100, "std" : 6 }
]
},
{
"_id" : 2,
"grades" : [
{ "grade" : 90, "mean" : 100, "std" : 6 },
{ "grade" : 87, "mean" : 100, "std" : 3 },
{ "grade" : 85, "mean" : 100, "std" : 4 }
]
}
] )

Para modificar o valor do campo std para todos os elementos na array grades em que a nota é maior ou igual a 80 e o std é maior ou igual a 5, use o operador posicional $[<identifier>] e arrayFilters:

db.students3.updateMany(
{ },
{ $inc: { "grades.$[elem].std" : -1 } },
{ arrayFilters: [ { "elem.grade": { $gte: 80 }, "elem.std": { $gte: 5 } } ] }
)

Após a operação, a coleção conta com os seguintes documentos:

{ "_id" : 1,
"grades" : [
{ "grade" : 80, "mean" : 75, "std" : 5 },
{ "grade" : 85, "mean" : 100, "std" : 4 },
{ "grade" : 85, "mean" : 100, "std" : 5 }
]
}
{
"_id" : 2,
"grades" : [
{ "grade" : 90, "mean" : 100, "std" : 5 },
{ "grade" : 87, "mean" : 100, "std" : 3 },
{ "grade" : 85, "mean" : 100, "std" : 4 }
]
}

Crie a coleção alumni:

db.alumni.insertMany( [
{
"_id": 1,
"name": "Christine Franklin",
"degrees": [
{ "level": "Master" },
{ "level": "Bachelor" }
],
},
{
"_id": 2,
"name": "Reyansh Sengupta",
"degrees": [ { "level": "Bachelor" } ],
}
] )

Para modificar todos os elementos da array degrees que não tenham "level": "Bachelor", use a operação posicional $[<identifier>] com o operador de query $ne:

db.alumni.updateMany(
{ },
{ $set : { "degrees.$[degree].gradcampaign" : 1 } },
{ arrayFilters : [ {"degree.level" : { $ne: "Bachelor" } } ] }
)

Após a operação, a coleção conta com os seguintes documentos:

{
_id: 1,
name: 'Christine Franklin',
degrees: [
{ level: 'Master', gradcampaign: 1 },
{ level: 'Bachelor' }
]
},
{
_id: 2,
name: 'Reyansh Sengupta',
degrees: [ { level: 'Bachelor' } ]
}

O operador posicional $[<identifier>] filtrado, em conjunto com o operador posicional $[] all, pode ser usado para atualizar arrays agrupadas.

Crie uma collection students4 com o seguinte documento:

db.students4.insertOne(
{ "_id" : 1,
"grades" : [
{ type: "quiz", questions: [ 10, 8, 5 ] },
{ type: "quiz", questions: [ 8, 9, 6 ] },
{ type: "hw", questions: [ 5, 4, 3 ] },
{ type: "exam", questions: [ 25, 10, 23, 0 ] },
]
}
)

O seguinte atualiza os valores que são maiores ou iguais a 8 na array grades.questions agrupada se o campo grades.type associado for quiz.

db.students4.updateMany(
{},
{ $inc: { "grades.$[t].questions.$[score]": 2 } },
{ arrayFilters: [ { "t.type": "quiz" }, { "score": { $gte: 8 } } ] }
)

Observação

Não adicione espaços em torno dos identificadores de array. Se você usar grades.$[ t ].questions.$[ score ] no exemplo anterior, o exemplo falhará.

Após a operação, a collection conta com o seguinte documento:

{
"_id" : 1,
"grades" : [
{ "type" : "quiz", "questions" : [ 12, 10, 5 ] },
{ "type" : "quiz", "questions" : [ 10, 11, 6 ] },
{ "type" : "hw", "questions" : [ 5, 4, 3 ] },
{ "type" : "exam", "questions" : [ 25, 10, 23, 0 ] }
]
}

Para atualizar todos os valores que são maiores ou iguais a 8 na array grades.questions agrupada, independentemente de type:

db.students4.updateMany(
{},
{ $inc: { "grades.$[].questions.$[score]": 2 } },
{ arrayFilters: [ { "score": { $gte: 8 } } ] }
)

Dica

Veja também:

Voltar

$[]