db.collection.updateMany()
MongoDB com drivers
Esta página documenta um método mongosh
. Para ver o método equivalente em um driver MongoDB, consulte a página correspondente da sua linguagem de programação:
Definição
Compatibilidade
Você pode utilizar o db.collection.updateMany()
para implantações hospedadas 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 método updateMany()
tem o seguinte formato:
db.collection.updateMany( <filter>, <update>, { upsert: <boolean>, writeConcern: <document>, collation: <document>, arrayFilters: [ <filterdocument1>, ... ], hint: <document|string>, let: <document> } )
Parâmetros
O método updateMany()
utiliza os seguintes parâmetros:
Parâmetro | Tipo | Descrição | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
documento | Os critérios de seleção para a atualização. Os mesmos seletores de consulta que no método Especifique um documento vazio | |||||||||||||||||||
documento ou pipeline | As modificações a serem aplicadas. Podem ser uma dos seguintes:
Para atualizar com um documento de substituição, consulte | |||||||||||||||||||
upsert | booleano | Opcional. Quando
Para evitar várias alterações, certifique-se de que os campos Padrão é | ||||||||||||||||||
writeConcern | documento | Opcional. Um documento que expressa o write concern. Omitir para usar o write concern padrão. Não defina explicitamente a preocupação de gravação para a operação se for executada em uma transação. Para usar write concern com transações, consulte Transações e write concern. | ||||||||||||||||||
collation | documento | Opcional. Especifica o agrupamento a ser usado para a operação. A colocação permite que os usuários especifiquem regras específicas do idioma para comparação de strings, como regras para letras maiúsculas e marcas de acento. A opção de agrupamento tem a seguinte sintaxe:
Ao especificar agrupamento, o campo Se o agrupamento não for especificado, mas a coleção tiver um agrupamento padrão (consulte Se nenhum agrupamento for especificado para a coleção ou para as operações, o MongoDB usa a comparação binária simples usada nas versões anteriores para comparações de strings. Você não pode especificar vários agrupamentos para uma operação. Por exemplo, você não pode especificar agrupamentos diferentes por campo ou, se estiver realizando uma busca com uma classificação, não poderá usar um agrupamento para a busca e outro para a classificação. Novidade na versão 3.4. | ||||||||||||||||||
arrayFilters | array | Opcional. Uma array de documentos de filtro que determina quais elementos da array modificar para uma operação de atualização em um campo da array. No documento de atualização, use o operador posicional filtrado O Você pode incluir o mesmo identificador várias vezes no documento de atualização; entretanto, para cada identificador distinto (
No entanto, você pode especificar condições compostas no mesmo identificador em um único documento de filtro, como nos exemplos a seguir:
Para obter exemplos, consulte Especificar Novidade na versão 3.6. | ||||||||||||||||||
Documento ou string | Opcional. Um documento ou string que especifica o índice a ser usado para dar suporte ao predicado de query. A opção pode usar um documento de especificação de índice ou a string do nome do índice. Se você especificar um índice que não existe, a operação emitirá erros. Para ver um exemplo, consulte Especificar | |||||||||||||||||||
let | Documento | Opcional. Especifica um documento com uma lista de variáveis. Isso permite que você melhore a legibilidade do comando separando as variáveis do texto da query. A sintaxe do documento é:
A variável é definida para o valor retornado pela expressão e não pode ser alterada posteriormente. Para acessar o valor de uma variável no comando, use o prefixo de dois cifrões ( Para usar uma variável para filtrar os resultados, você deve acessar a variável dentro do operador Para ver um exemplo completo com |
Devoluções
O método retorna um documento que contém:
Um valor booleano
acknowledged
comotrue
se a operação for executada com preocupação de gravaçãorefer oufalse
se a preocupação de gravação estiver desativadamatchedCount
contendo o número de documentos correspondentesmodifiedCount
contendo o número de documentos modificadosupsertedId
contendo o_id
para o documento atualizadoupsertedCount
contendo o número de documentos upserted
Controle de acesso
Em implantações executadas com authorization
, o usuário deve ter acesso que inclua os seguintes privilégios:
update
ação na(s) coleção(ões) especificada(s).find
ação na(s) coleção(ões) especificada(s).insert
ação na(s) coleção(s) especificada(s) se a operação resultar em um upsert.
A função embutida readWrite
fornece os privilégios exigidos.
Comportamento
updateMany()
atualiza todos os documentos correspondentes na coleção que corresponde ao filter
, usando os critérios do update
para aplicar modificações.
Upsert
Se upsert: true
e nenhum documento corresponder a filter
, db.collection.updateMany()
cria um novo documento com base nos parâmetros filter
e update
.
Se você especificar upsert: true
em uma coleção fragmentada, deverá incluir a chave de fragmento completa em filter
. Para comportamento adicional do db.collection.updateMany()
, consulte Coleções fragmentadas.
Atualizar com um Documento de Expressões do Operador de Atualização
Para a especificação de modificação, o método db.collection.updateMany()
pode aceitar um documento que contém somente expressões de operador de atualização a serem executadas.
Por exemplo:
db.collection.updateMany( <query>, { $set: { status: "D" }, $inc: { quantity: 2 } }, ... )
Atualize com um pipeline de agregação.
O método db.collection.updateMany()
pode aceitar um pipeline de agregação [ <stage1>, <stage2>, ... ]
que especifica as modificações a serem realizadas. O pipeline pode consistir nas seguintes etapas:
$addFields
e seu alias$set
$replaceRoot
e seu nome alternativo$replaceWith
.
O uso do aggregation pipeline permite uma instrução de atualização mais expressiva, como atualizações condicionais Express com base em valores de campo atuais ou atualização de um campo usando o valor de outro(s) campo(s).
Por exemplo:
db.collection.updateMany( <query>, [ { $set: { status: "Modified", comments: [ "$misc1", "$misc2" ] } }, { $unset: [ "misc1", "misc2" ] } ] ... )
Observação
Nesse pipeline, $set
e $unset
são estágios de agregação, diferentes dos operadores de atualização. Os estágios de agregação $set
e $unset
adicionam novos campos aos documentos e não modificam os valores dos campos existentes.
Para obter mais informações sobre os operadores de atualização, consulte $set
e $unset
.
Para obter exemplos, consulte Atualizar com pipeline de agregação.
Capped collections
Se uma operação de atualização alterar o tamanho do documento, a operação falhará.
Coleções de Time Series
O método updateMany()
está disponível para coleções de séries temporais a partir do MongoDB 5.1.
Coleções fragmentadas
Para uma operação db.collection.updateMany()
que inclui upsert: true
e está em uma coleção fragmentada, você deve incluir a chave de fragmento completa no filter
.
Explicabilidade
updateMany()
não é compatível com db.collection.explain()
.
Transações
db.collection.updateMany()
pode ser usado dentro de transações distribuídas.
Importante
Na maioria dos casos, uma transação distribuída incorre em um custo de desempenho maior do que as gravações de um único documento, e a disponibilidade de transações distribuídas não deve substituir o design eficaz do esquema. Em muitos cenários, o modelo de dados desnormalizado (documentos e arrays incorporados) continuará a ser ideal para seus dados e casos de uso. Ou seja, para muitos cenários, modelar seus dados adequadamente minimizará a necessidade de transações distribuídas.
Para considerações adicionais sobre o uso de transações (como limite de tempo de execução e limite de tamanho do oplog), consulte também Considerações de produção.
Inserção nas Transações
Você pode criar coleção e indexes dentro de uma transaction distribuída se a transaction não for uma transação de escrita de estilhaço cruzado.
db.collection.updateMany()
com upsert: true
pode ser executado em uma coleção existente ou em uma coleção inexistente. Se for executada em uma coleção inexistente, a operação cria a coleção.
Write concerns e transações
Não defina explicitamente a preocupação de gravação para a operação se for executada em uma transação. Para usar write concern com transações, consulte Transações e write concern.
Entradas de oplog
Se uma operação db.collection.updateMany()
conseguir atualizar um ou mais documentos, ela adicionará uma entrada no oplog (log de operações) referente a cada documento atualizado. Se a operação falhar ou não encontrar nenhum documento para atualizar, ela não adicionará uma entrada no oplog.
Exemplos
Atualizar vários documentos
A coleção restaurant
contém os seguintes documentos:
{ "_id" : 1, "name" : "Central Perk Cafe", "violations" : 3 } { "_id" : 2, "name" : "Rock A Feller Bar and Grill", "violations" : 2 } { "_id" : 3, "name" : "Empire State Sub", "violations" : 5 } { "_id" : 4, "name" : "Pizza Rat's Pizzaria", "violations" : 8 }
A operação a seguir atualiza todos os documentos em que violations
é maior que 4
e $set
é um sinalizador para revisão:
try { db.restaurant.updateMany( { violations: { $gt: 4 } }, { $set: { "Review" : true } } ); } catch (e) { print(e); }
A operação retorna:
{ "acknowledged" : true, "matchedCount" : 2, "modifiedCount" : 2 }
A coleção agora contém os seguintes documentos:
{ "_id" : 1, "name" : "Central Perk Cafe", "violations" : 3 } { "_id" : 2, "name" : "Rock A Feller Bar and Grill", "violations" : 2 } { "_id" : 3, "name" : "Empire State Sub", "violations" : 5, "Review" : true } { "_id" : 4, "name" : "Pizza Rat's Pizzaria", "violations" : 8, "Review" : true }
Se nenhuma correspondência for encontrada, a operação retornará:
{ "acknowledged" : true, "matchedCount" : 0, "modifiedCount" : 0 }
A configuração upsert: true
inseriria um documento se nenhuma correspondência fosse encontrada.
Atualização com aggregation pipeline
O db.collection.updateMany()
pode utilizar um pipeline de agregação para a atualização. O pipeline pode consistir nas seguintes etapas:
$addFields
e seu alias$set
$replaceRoot
e seu nome alternativo$replaceWith
.
O uso do aggregation pipeline permite uma instrução de atualização mais expressiva, como atualizações condicionais Express com base em valores de campo atuais ou atualização de um campo usando o valor de outro(s) campo(s).
Exemplo 1: Atualização com Pipeline de Agregação Usando Campos Existentes
Os exemplos a seguir usam o aggregation pipeline para modificar um campo usando os valores de outros campos no documento.
Criar uma coleção students
com os seguintes documentos:
db.students.insertMany( [ { "_id" : 1, "student" : "Skye", "points" : 75, "commentsSemester1" : "great at math", "commentsSemester2" : "loses temper", "lastUpdate" : ISODate("2019-01-01T00:00:00Z") }, { "_id" : 2, "students" : "Elizabeth", "points" : 60, "commentsSemester1" : "well behaved", "commentsSemester2" : "needs improvement", "lastUpdate" : ISODate("2019-01-01T00:00:00Z") } ] )
Suponha que, em vez de separar os campos commentsSemester1
e commentsSemester2
, você queira reuni-los em um novo campo comments
. A seguinte operação de atualização usa um pipeline de agregação para:
adicione o novo campo
comments
e defina o campolastUpdate
.remova os campos
commentsSemester1
ecommentsSemester2
de todos os documentos da coleção.
db.students.updateMany( { }, [ { $set: { comments: [ "$commentsSemester1", "$commentsSemester2" ], lastUpdate: "$$NOW" } }, { $unset: [ "commentsSemester1", "commentsSemester2" ] } ] )
Observação
Nesse pipeline, $set
e $unset
são estágios de agregação, diferentes dos operadores de atualização. Os estágios de agregação $set
e $unset
adicionam novos campos aos documentos e não modificam os valores dos campos existentes.
Para obter mais informações sobre os operadores de atualização, consulte $set
e $unset
.
- Primeira etapa
O estágio
$set
:cria um novo campo de array
comments
cujos elementos são o conteúdo atual dos camposcommentsSemester1
ecommentsSemester2
edefine o campo
lastUpdate
para o valor da variável de agregaçãoNOW
. A variável de agregaçãoNOW
é resolvida para o valor de data e hora atual e permanece a mesma em todo o pipeline. Para acessar variáveis de agregação, prefixe a variável com cifrões duplos$$
e coloque entre aspas.
- Segunda etapa
- O estágio
$unset
remove os camposcommentsSemester1
ecommentsSemester2
.
Após o comando, a coleção contém os seguintes documentos:
{ "_id" : 1, "student" : "Skye", "status" : "Modified", "points" : 75, "lastUpdate" : ISODate("2020-01-23T05:11:45.784Z"), "comments" : [ "great at math", "loses temper" ] } { "_id" : 2, "student" : "Elizabeth", "status" : "Modified", "points" : 60, "lastUpdate" : ISODate("2020-01-23T05:11:45.784Z"), "comments" : [ "well behaved", "needs improvement" ] }
Exemplo 2: Atualização com Pipeline de Agregação Usando Campos Existentes Condicionalmente
O aggregation pipeline permite que a atualização execute atualizações condicionais com base nos valores de campo atuais, bem como use valores de campo atuais para calcular um valor de campo separado.
Por exemplo, criar uma coleção students3
com os seguintes documentos:
db.students3.insertMany( [ { "_id" : 1, "tests" : [ 95, 92, 90 ], "lastUpdate" : ISODate("2019-01-01T00:00:00Z") }, { "_id" : 2, "tests" : [ 94, 88, 90 ], "lastUpdate" : ISODate("2019-01-01T00:00:00Z") }, { "_id" : 3, "tests" : [ 70, 75, 82 ], "lastUpdate" : ISODate("2019-01-01T00:00:00Z") } ] )
Usando um aggregation pipeline, você pode atualizar os documentos com a média calculada e a nota por letra.
db.students3.updateMany( { }, [ { $set: { average : { $trunc: [ { $avg: "$tests" }, 0 ] } , lastUpdate: "$$NOW" } }, { $set: { grade: { $switch: { branches: [ { case: { $gte: [ "$average", 90 ] }, then: "A" }, { case: { $gte: [ "$average", 80 ] }, then: "B" }, { case: { $gte: [ "$average", 70 ] }, then: "C" }, { case: { $gte: [ "$average", 60 ] }, then: "D" } ], default: "F" } } } } ] )
Observação
Nesse pipeline, $set
e $unset
são estágios de agregação, diferentes dos operadores de atualização. Os estágios de agregação $set
e $unset
adicionam novos campos aos documentos e não modificam os valores dos campos existentes.
Para obter mais informações sobre os operadores de atualização, consulte $set
e $unset
.
- Primeira etapa
O estágio
$set
:calcula um novo campo
average
com base na média do campotests
. Consulte$avg
para obter mais informações sobre o operador de agregação do$avg
e$trunc
para obter mais informações sobre o operador de agregação truncada$trunc
.define o campo
lastUpdate
para o valor da variável de agregaçãoNOW
. A variável de agregaçãoNOW
é resolvida para o valor de data e hora atual e permanece a mesma em todo o pipeline. Para acessar variáveis de agregação, prefixe a variável com cifrões duplos$$
e coloque entre aspas.
- Segunda etapa
- O estágio
$set
calcula um novo campograde
com base no campoaverage
calculado no estágio anterior. Consulte$switch
para obter mais informações sobre o operador de aggregation do$switch
.
Após o comando, a coleção contém os seguintes documentos:
{ "_id" : 1, "tests" : [ 95, 92, 90 ], "lastUpdate" : ISODate("2020-01-24T17:31:01.670Z"), "average" : 92, "grade" : "A" } { "_id" : 2, "tests" : [ 94, 88, 90 ], "lastUpdate" : ISODate("2020-01-24T17:31:01.670Z"), "average" : 90, "grade" : "A" } { "_id" : 3, "tests" : [ 70, 75, 82 ], "lastUpdate" : ISODate("2020-01-24T17:31:01.670Z"), "average" : 75, "grade" : "C" }
Atualizar Vários Documentos com Inserção
A coleção inspectors
contém os seguintes documentos:
{ "_id" : 92412, "inspector" : "F. Drebin", "Sector" : 1, "Patrolling" : true }, { "_id" : 92413, "inspector" : "J. Clouseau", "Sector" : 2, "Patrolling" : false }, { "_id" : 92414, "inspector" : "J. Clouseau", "Sector" : 3, "Patrolling" : true }, { "_id" : 92415, "inspector" : "R. Coltrane", "Sector" : 3, "Patrolling" : false }
A operação a seguir atualiza todos os documentos com Sector
maior que 4 e inspector
igual a "R. Coltrane"
:
try { db.inspectors.updateMany( { "Sector" : { $gt : 4 }, "inspector" : "R. Coltrane" }, { $set: { "Patrolling" : false } }, { upsert: true } ); } catch (e) { print(e); }
A operação retorna:
{ "acknowledged" : true, "matchedCount" : 0, "modifiedCount" : 0, "upsertedId" : ObjectId("56fc5dcb39ee682bdc609b02"), "upsertedCount": 1 }
A coleção agora contém os seguintes documentos:
{ "_id" : 92412, "inspector" : "F. Drebin", "Sector" : 1, "Patrolling" : true }, { "_id" : 92413, "inspector" : "J. Clouseau", "Sector" : 2, "Patrolling" : false }, { "_id" : 92414, "inspector" : "J. Clouseau", "Sector" : 3, "Patrolling" : true }, { "_id" : 92415, "inspector" : "R. Coltrane", "Sector" : 3, "Patrolling" : false }, { "_id" : ObjectId("56fc5dcb39ee682bdc609b02"), "inspector" : "R. Coltrane", "Patrolling" : false }
Como nenhum documento correspondeu ao filtro e upsert
era true
, updateMany()
inseriu o documento com um _id
gerado, as condições de igualdade de filter
e os modificadores de update
.
Atualize com preocupação de gravação
Dado um conjunto de réplicas de três membros, a operação a seguir especifica um w
de majority
e wtimeout
de 100
try { db.restaurant.updateMany( { "name" : "Pizza Rat's Pizzaria" }, { $inc: { "violations" : 3}, $set: { "Closed" : true } }, { w: "majority", wtimeout: 100 } ); } catch (e) { print(e); }
Se a confirmação demorar mais que o limite wtimeout
, a seguinte exceção será lançada:
WriteConcernError({ "code" : 64, "errmsg" : "waiting for replication timed out", "errInfo" : { "wtimeout" : true, "writeConcern" : { "w" : "majority", "wtimeout" : 100, "provenance" : "getLastErrorDefaults" } } })
A tabela a seguir explica os possíveis valores de errInfo.writeConcern.provenance
:
Proveniência | Descrição |
---|---|
clientSupplied | A preocupação de gravação foi especificada no aplicativo. |
customDefault | A preocupação de gravação originou-se de um valor padrão personalizado definido. Consulte setDefaultRWConcern . |
getLastErrorDefaults | A preocupação de gravação originada do campo settings.getLastErrorDefaults do conjunto de réplicas. |
implicitDefault | A preocupação de gravação originou-se do servidor na ausência de todas as outras especificações de preocupação de gravação. |
Especifique o agrupamento
Novidade na versão 3.4.
A colocação permite que os usuários especifiquem regras específicas do idioma para comparação de strings, como regras para letras maiúsculas e marcas de acento.
Uma coleção myColl
possui os seguintes documentos:
{ _id: 1, category: "café", status: "A" } { _id: 2, category: "cafe", status: "a" } { _id: 3, category: "cafE", status: "a" }
A seguinte operação inclui a opção coleção:
db.myColl.updateMany( { category: "cafe" }, { $set: { status: "Updated" } }, { collation: { locale: "fr", strength: 1 } } );
Especificar arrayFilters
para operações de atualização de array
Ao atualizar um campo de array, você pode especificar arrayFilters
que determinam quais elementos de array atualizar.
Atualizar elementos que correspondem aos critérios arrayFilters
Crie uma collection students
com os seguintes documentos:
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
na array grades
, utilize o operador posicional filtrado $[<identifier>]
com a opção arrayFilters
:
db.students.updateMany( { grades: { $gte: 100 } }, { $set: { "grades.$[element]" : 100 } }, { arrayFilters: [ { "element": { $gte: 100 } } ] } )
Após a operação, a coleção contém os seguintes documentos:
{ "_id" : 1, "grades" : [ 95, 92, 90 ] } { "_id" : 2, "grades" : [ 98, 100, 100 ] } { "_id" : 3, "grades" : [ 95, 100, 100 ] }
Atualizar elementos específicos de uma array de documentos
Crie uma collection students2
com os seguintes documentos:
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 da array grades
onde a nota é maior ou igual a 85
, use o operador posicional filtrado com $[<identifier>]
o 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 } ] }
Especifique hint
para operações de atualização
Criar uma coleção students
de amostra com os seguintes documentos:
db.students.insertMany( [ { "_id" : 1, "student" : "Richard", "grade" : "F", "points" : 0, "comments1" : null, "comments2" : null }, { "_id" : 2, "student" : "Jane", "grade" : "A", "points" : 60, "comments1" : "well behaved", "comments2" : "fantastic student" }, { "_id" : 3, "student" : "Ronan", "grade" : "F", "points" : 0, "comments1" : null, "comments2" : null }, { "_id" : 4, "student" : "Noah", "grade" : "D", "points" : 20, "comments1" : "needs improvement", "comments2" : null }, { "_id" : 5, "student" : "Adam", "grade" : "F", "points" : 0, "comments1" : null, "comments2" : null }, { "_id" : 6, "student" : "Henry", "grade" : "A", "points" : 86, "comments1" : "fantastic student", "comments2" : "well behaved" } ] )
Crie os seguintes índices na coleção:
db.students.createIndex( { grade: 1 } )
A seguinte operação de atualização sugere explicitamente o uso do índice {
grade: 1 }
:
Observação
Se você especificar um índice que não existe, a operação emitirá erros.
db.students.updateMany( { "points": { $lte: 20 }, "grade": "F" }, { $set: { "comments1": "failed class" } }, { hint: { grade: 1 } } )
O comando de atualização retorna o seguinte:
{ "acknowledged" : true, "matchedCount" : 3, "modifiedCount" : 3 }
Para ver se o índice sugerido é usado, execute o pipeline $indexStats
:
db.students.aggregate( [ { $indexStats: { } }, { $sort: { name: 1 } }, { $match: {key: { grade: 1 } } } ] )