Você pode usar operadores posicionais com a linguagem de query do MongoDB (MQL) para atualizar documentos que contêm arrays sem substituir a array ou anexar a ela.
Este tutorial apresenta vários casos de uso para operadores posicionais dentro do MongoDB.
Antes de começar
Instale o mongosh.
Conecte-se a uma implantação.
Use
mongosh
para inserir documentos em uma nova coleção no banco de dadostest
padrão:db.employees.insertMany( [ { _id: 'SF', engineering: [ { name: 'Alice', email: 'missingEmail', salary: 100000 }, { name: 'Bob', email: 'missingEmail', salary: 75000 } ], sales: [ { name: 'Charlie', email: 'charlie@mail.com', salary: 90000, bonus: 1000 } ] }, { _id: 'NYC', engineering: [ { name: 'Dave', email: 'dave@mail.com', salary: 55000 }, ], sales: [ { name: 'Ed', email: 'ed@mail.com', salary: 99000, bonus: 2000 }, { name: 'Fran', email: 'fran@mail.com', salary: 50000, bonus: 10000 } ] } ] );
Passos
Os exemplos a seguir mostram como:
Use o operador $ para atualizar a primeira correspondência em uma array
Use o operador $ com $elemMatch para atualizar um elemento específico
Use o operador $[] para atualizar todos os elementos de array em um documento
Use o operador $[<identifier>] para atualizar elementos que correspondem a uma condição de filtro
Use o operador $ para atualizar a primeira correspondência em uma array
Para atualizar apenas a primeira correspondência em uma array, use o operador $
. O operador $
atua como um espaço reservado para atualizar o primeiro elemento correspondente.
O exemplo a seguir usa o método updateOne()
com os operadores $
e $set
para atualizar o primeiro e-mail que tem o valor missingEmail
na array engineering
para alice@mail.com
.
1 db.employees.updateOne( 2 { "engineering.email": "missingEmail" }, 3 { "$set": { "engineering.$.email": "alice@mail.com" } } 4 );
Use o método find()
para confirmar a atualização no e-mail de Alice.
db.employees.find()
[ { _id: 'SF', engineering: [ { name: 'Alice', email: 'alice@mail.com', salary: 100000 }, { name: 'Bob', email: 'missingEmail', salary: 75000 } ], sales: [ { name: 'Charlie', email: 'charlie@mail.com', salary: 90000, bonus: 1000 } ] }, { _id: 'NYC', engineering: [ { name: 'Dave', email: 'dave@mail.com', salary: 55000 } ], sales: [ { name: 'Ed', email: 'ed@mail.com', salary: 99000, bonus: 2000 }, { name: 'Fran', email: 'fran@mail.com', salary: 50000, bonus: 10000 } ] } ]
Conforme o exemplo acima, depois de filtrar documentos que tenham um elemento de array com o campo engineering.email
definido como missingEmail
, o operador $
atualiza somente a primeira ocorrência que corresponde ao filtro.
Use o operador $ com $elemMatch para atualizar um elemento específico
Para atualizar um elemento específico, você pode usar o operador $elemMatch
.
O exemplo a seguir usa o operador $elemMatch
e o operador $
para atualizar o email
de Rob para "bob@mail.com"
.
1 db.employees.updateOne( 2 { engineering: { $elemMatch: { name: "Bob", email: "missingEmail" } } }, 3 { $set: { "engineering.$.email": "bob@mail.com" } } 4 );
Use o método find()
para confirmar a atualização no e-mail de Rob.
db.employees.find( { "engineering": { $elemMatch: { name: "Bob" } } }, { "engineering.$": 1, _id: 0 } );
[ { engineering: [ { name: 'Bob', email: 'bob@mail.com', salary: 75000 } ] } ]
Use o operador $[] para atualizar todos os elementos de array em um documento
Para atualizar todos os elementos de uma array com uma única operação, use o operador $[]
.
Considere um caso em que você deseja oferecer um Bônus adicional de $2,000 para seus funcionários de vendas em Nova York. Você pode usar o método updateMany()
com o operador $[]
e o operador $inc
para aumentar todos os campos bonus
dentro da array sales
no documento NYC
em 2000
.
1 db.employees.updateMany( 2 { "_id": "NYC" }, 3 { "$inc": { "sales.$[].bonus": 2000 } } 4 );
Use o método find()
para confirmar a atualização nos campos bonus
dos funcionários da equipe de vendas de Nova York.
db.employees.find( { _id: "NYC" }, { sales: 1, _id: 0 } );
[ { sales: [ { name: 'Ed', email: 'ed@mail.com', salary: 99000, bonus: 4000 }, { name: 'Fran', email: 'fran@mail.com', salary: 50000, bonus: 12000 } ] } ]
Use o operador $[<identifier>] para atualizar elementos que correspondem a uma condição de filtro
Para atualizar vários elementos de array em uma única operação sem código excessivo do lado do cliente emparelhado com uma operação de substituição, use o operador $[<identifier>]
. O operador $[<identifier>]
atua como um espaço reservado para atualizar todos os elementos que correspondem a uma condição arrayFilters.
Considere um caso em que você deseja atualizar os salários de funcionários específicos se eles atenderem a uma série de condições. Você pode usar o updateMany()
método com o $[<identifier>]
operador para realizar essa tarefa.
1 db.employees.updateMany( 2 {}, 3 { 4 "$set": { 5 "engineering.$[elemX].salary": 95000, 6 "sales.$[elemY].salary": 75000 7 } 8 }, 9 { 10 "arrayFilters": [ 11 { "elemX.name": "Bob", "elemX.salary": 75000 }, 12 { "elemY.name": "Ed", "elemY.salary": 50000, } 13 ] 14 } 15 );
No exemplo acima, o primeiro parâmetro é uma correspondência vazia para avaliar todos os documentos na collection.
elemX
e elemY
representam dois arrayFiltersdiferentes:
Para corresponder a
elemX
, um objeto de array deve ter um camponame
deBob
e umsalary
de75000
.Para corresponder a
elemY
, um objeto de array deve ter um camponame
deEd
e umsalary
de50000
.
Se um item de array no documento corresponder ao filtro elemX
, então updateMany()
definirá o campo salary
para o objeto como 95000
. Se um item de array corresponder ao filtro elemY
, então updateMany()
definirá o campo salary
para o objeto como 75000
. Se um filtro não corresponder, a operação $set
correspondente não será acionada.
Use o método find()
para confirmar a atualização no salário de Rob porque ele atende a ambas as condições elemX
.
db.employees.find( { "engineering.name": "Bob" }, { engineering: { $elemMatch: { name: "Bob" } }, _id: 0 } );
[ { engineering: [ { name: "Bob", email: "bob@mail.com", salary: 95000 } ] } ]
Use o método find()
para confirmar que a atualização do salário de Ricardo não foi bem-sucedida porque ele não atende às condições elemX
ou elemY
.
db.employees.find( { "sales.name": "Ed" }, { sales: { $elemMatch: { name: "Ed" } }, _id: 0 } );
[ { sales: [ { name: "Ed", email: "ed@mail.com", salary: 99000, bonus: 4000 } ] } ]
Conclusão
Este tutorial ensina alguns dos operadores posicionais dentro da linguagem de query MongoDB (MQL). Esses operadores são úteis ao trabalhar com arrays, pois evitam que você tenha que fazer substituições completas na array ou manipulação estendida do lado do cliente . Para saber mais sobre MQL, consulte Iniciar com Atlas.
Para saber mais sobre operadores de atualização no MongoDB, consulte Operadores de atualização.