$[<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
$[]
Definição
$[<identifier>]
O operador posicional filtrado
$[<identifier>]
identifica os elementos de array que correspondem às condiçõesarrayFilters
para uma operação de atualização, por exemplo,db.collection.updateMany()
edb.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
.
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.
Restrições
A opção arrayFilters
não pode incluir os seguintes operadores de query:
upsert
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.
Arrays agrupadas
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 $[]
.
Exemplos
Atualizar todos os elementos de array que correspondem arrayFilters
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 ] }
Atualizar todos os documentos que correspondem a arrayFilters
em uma array
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 } ] }
Atualizar todos os elementos de array que correspondem a várias condições
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 } ] }
Atualizar elementos de array usando um operador de negação
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' } ] }
Atualizar matrizes agrupadas em conjunto com $[]
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 } } ] } )