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

db.collection.update()

Nesta página

  • Definição
  • Compatibilidade
  • Sintaxe
  • Controle de acesso
  • Comportamento
  • Exemplos
  • WriteResult

Importante

Método de mongosh obsoleto

Esse método está obsoleto em mongosh. Para obter métodos alternativos, consulte Alterações de compatibilidade com o shell mongo legado.

db.collection.update(query, update, options)

Modifica um documento ou documentos existentes em uma coleção. O método pode modificar campos específicos de um documento ou documentos existentes ou substituir um documento existente completamente, dependendo do parâmetro de atualização.

Por padrão, o método db.collection.update() atualiza um documento único. Inclua a opção multi: true para atualizar todos os documentos que correspondam aos critérios de query.

Você pode utilizar o db.collection.update() 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

Para saber como atualizar documentos hospedados no MongoDB Atlas usando a IU do Atlas, consulte Editar um documento.

Alterado na versão 5.0.

O método db.collection.update() tem o seguinte formato:

db.collection.update(
<query>,
<update>,
{
upsert: <boolean>,
multi: <boolean>,
writeConcern: <document>,
collation: <document>,
arrayFilters: [ <filterdocument1>, ... ],
hint: <document|string>,
let: <document> // Added in MongoDB 5.0
}
)

O método db.collection.update() 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 find() estão disponíveis.

Quando você executar um update() com upsert: true e a query não corresponder a nenhum documento existente, o MongoDB irá se recusar a inserir um novo documento se a query especificar condições no campo _id usando notação de ponto.

documento ou pipeline

As modificações a serem aplicadas. Podem ser uma dos seguintes:

Contém apenas <field1>: <value1> pares.

Contém apenas os seguintes estágios de agregação:

Para ver detalhes e exemplos, consulte Entradas de oplog.

booleano

Opcional. Quando true, update() ou:

  • Cria um novo documento se nenhum documento corresponder a query. Para obter mais detalhes, consulte upsert behavior.

  • Atualiza um único documento que corresponda a query.

Se upsert e multi forem "true" e nenhum documento corresponder à consulta, a operação de atualização inserirá apenas um único documento.

Para evitar várias upserts, certifique-se de que os campos de query sejam indexados de forma exclusiva. Consulte Upsert com valores duplicados para obter um exemplo.

O padrão é false, que não insere um novo documento quando nenhuma correspondência é encontrada.

booleano

Opcional. Se definido como true, atualiza vários documentos que atendem aos critérios query . Se definido como false, atualiza um documento. O valor padrão é false. Para obter mais informações, consulte Exemplos de atualização de vários documentos.

documento

Opcional. Um documento expressando preocupação de gravação. Omita o uso da preocupação de gravação w: "majority" 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.

Para obter um exemplo usando writeConcern, consulte Substituir preocupação de gravação padrão.

documento

Opcional.

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.

Para ver um exemplo usando collation, consulte Especificar agrupamento.

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, utilize o $[<identifier>] para definir um identificador para atualizar somente os elementos de array que correspondem ao documento de filtro correspondente no arrayFilters.

Você não pode ter um documento de filtro de array para um identificador se o identificador não estiver incluído no documento de atualização.

Para obter exemplos, consulte Especificar arrayFilters para operações de atualização de array.

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 hint para Operações de Atualização.

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 é:

{
<variable_name_1>: <expression_1>,
...,
<variable_name_n>: <expression_n>
}

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 ($$) junto com o nome da variável no formato $$<variable_name>. Por exemplo: $$targetTotal.

Para usar uma variável para filtrar os resultados, você deve acessar a variável dentro do operador $expr.

Para um exemplo completo utilizando let e variáveis, consulte Utilizar Variáveis no let.

Novidades na versão 5.0.

O método retorna um documento WriteResult que contém o status da operação.

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.

A tentativa de usar o operador $expr com o sinalizador upsert definido como true gerará um erro.

Para usar db.collection.update() com multi: false em uma coleção fragmentada, é necessário incluir uma correspondência exata no campo _id ou direcionar um único fragmento (por exemplo, incluindo a chave do fragmento).

Quando o db.collection.update() executar operações de atualização (e não documentar operações de substituição), o db.collection.update() poderá direcionar vários fragmentos.

Dica

Veja também:

As operações de substituição de documentos tentam direcionar um único fragmento, primeiro usando o filtro de query. Se a operação não puder direcionar um único fragmento pelo filtro de query, ela tentará direcionar pelo documento de substituição.

Em versões anteriores, a operação tenta direcionar usando o documento de substituição.

No caso das operações de db.collection.update() que incluam upsert: true e estejam em uma coleção fragmentada, você deve incluir a chave de fragmento completa no filter:

  • Para uma operação de atualização.

  • Para uma operação de substituição de documento.

No entanto, os documentos em uma coleção fragmentada podem estar faltando os campos de chave de fragmento. Para direcionar um documento que não possui a chave de fragmento, você pode usar a null correspondência de igualdade em conjunto com outra condição de filtro (como no campo _id ). Por exemplo:

{ _id: <value>, <shardkeyfield>: null } // _id of the document missing shard key

Você pode atualizar o valor da chave de fragmento de um documento, a menos que o campo de chave de fragmento seja o campo de _id imutável.

Para modificar o valor da chave de fragmento existente com db.collection.update():

Dica

Como um valor de chave ausente é retornado como parte de uma correspondência de igualdade nula, para evitar a atualização de uma chave de valor nulo, inclua condições de consulta (como no campo _id) conforme apropriado.

Consulte também upsert em uma coleção fragmentada.

Os documentos em coleções fragmentadas podem não ter os campos de chave de fragmento. Para usar db.collection.update() a fim de definir a chave de fragmento ausente do documento, é necessário executar em um mongos. Não emita a operação diretamente no fragmento.

Além disso, os seguintes requisitos também se aplicam:

Tarefa
Requisitos
Para definir como null
  • Pode especificar multi: true.

  • Requer filtro de igualdade na chave de fragmento completa se upsert: true.

Para definir um valor diferente de null
  • Deve ser executado dentro de uma transação ou como uma gravação repetível.

  • Deve especificar multi: false.

  • Requer filtro de equivalência na chave de fragmento completa se:

    • upsert: true, ou

    • se usar um documento de substituição e o novo valor da chave de shard pertencer a um shard diferente.

Dica

Como um valor de chave ausente é retornado como parte de uma correspondência de igualdade nula, para evitar a atualização de uma chave de valor nulo, inclua condições de consulta (como no campo _id) conforme apropriado.

Veja também:

db.collection.update() 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.

Você pode criar coleção e índices dentro de uma transação distribuída se a transação não for uma transação de gravação cross-fragmento.

db.collection.update() 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.

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.

Se uma operação db.collection.update() atualizar um ou mais documentos com êxito, a operação adicionará uma entrada no oplog (log de operações). Se a operação falhar ou não encontrar nenhum documento para atualizar, a operação não adicionará uma entrada no oplog.

As abas a seguir mostram uma variedade de operações comuns de update().

No mongosh, crie uma coleção books que contenha os seguintes documentos. Este comando remove primeiro todos os documentos existentes anteriormente da coleção books:

db.books.remove({});
db.books.insertMany([
{
"_id" : 1,
"item" : "TBD",
"stock" : 0,
"info" : { "publisher" : "1111", "pages" : 430 },
"tags" : [ "technology", "computer" ],
"ratings" : [ { "by" : "ijk", "rating" : 4 }, { "by" : "lmn", "rating" : 5 } ],
"reorder" : false
},
{
"_id" : 2,
"item" : "XYZ123",
"stock" : 15,
"info" : { "publisher" : "5555", "pages" : 150 },
"tags" : [ ],
"ratings" : [ { "by" : "xyz", "rating" : 5 } ],
"reorder" : false
}
]);

Se o documento <update> contiver modificadores operador de atualização, como aqueles que utilizam o modificador $set, então:

  • O documento <update> deve conter somente expressões do operador de atualização.

  • O método db.collection.update() atualiza somente os campos correspondentes no documento.

    • Para atualizar um documento incorporado ou uma array como um todo, especifique o valor de substituição para o campo.

    • Para atualizar campos específicos em um documento incorporado ou em uma array, use notação de ponto para especificar o campo.

db.books.update(
{ _id: 1 },
{
$inc: { stock: 5 },
$set: {
item: "ABC123",
"info.publisher": "2222",
tags: [ "software" ],
"ratings.1": { by: "xyz", rating: 3 }
}
}
)

Nesta operação:

  • O parâmetro <query> do { _id: 1 } especifica qual documento atualizar,

  • o operador $inc incrementa o campo stock e

  • o operador $set substitui o valor do

    • item campo,

    • publisher campo no documento incorporado info,

    • tags campo e

    • segundo elemento na array ratings.

O documento atualizado é o seguinte:

{
"_id" : 1,
"item" : "ABC123",
"stock" : 5,
"info" : { "publisher" : "2222", "pages" : 430 },
"tags" : [ "software" ],
"ratings" : [ { "by" : "ijk", "rating" : 4 }, { "by" : "xyz", "rating" : 3 } ],
"reorder" : false
}

Esta operação corresponde à seguinte declaração SQL:

UPDATE books
SET stock = stock + 5
item = "ABC123"
publisher = 2222
pages = 430
tags = "software"
rating_authors = "ijk,xyz"
rating_values = "4,3"
WHERE _id = 1

Se o parâmetro query corresponder a vários documentos, a operação atualizará somente um documento correspondente. Para atualizar vários documentos, defina a opção multi como true.

A operação a seguir usa o operador de atualização $push para acrescentar um novo objeto à array ratings.

db.books.update(
{ _id: 2 },
{
$push: { ratings: { "by" : "jkl", "rating" : 2 } }
}
)

O documento atualizado é o seguinte:

{
"_id" : 2,
"item" : "XYZ123",
"stock" : 15,
"info" : {
"publisher" : "5555",
"pages" : 150
},
"tags" : [ ],
"ratings" : [
{ "by" : "xyz", "rating" : 5 },
{ "by" : "jkl", "rating" : 2 }
],
"reorder" : false
}

Dica

Veja também:

A operação a seguir usa o operador $unset para remover o campo tags do documento com { _id: 1 }.

db.books.update( { _id: 1 }, { $unset: { tags: 1 } } )

O documento atualizado é o seguinte:

{
"_id" : 1,
"item" : "TBD",
"stock" : 0,
"info" : {
"publisher" : "1111",
"pages" : 430
},
"ratings" : [ { "by" : "ijk", "rating" : 4 }, { "by" : "lmn", "rating" : 5 } ],
"reorder" : false
}

Não existe um SQL direto equivalente a $unset; no entanto, $unset é semelhante ao seguinte comando SQL que remove o campo tags da tabela books :

ALTER TABLE books
DROP COLUMN tags

Se multi estiver definido como true, o método db.collection.update() atualiza todos os documentos que atendem aos critérios <query>. A operação de atualização multi pode ser intercalada com outras operações de leitura/gravação.

A operação a seguir define o campo reorder como true para todos os documentos em que stock é menor ou igual a 10. Se o campo reorder não existir no(s) documento(s) correspondente(s), o operador $set adicionará o campo com o valor especificado.

db.books.update(
{ stock: { $lte: 10 } },
{ $set: { reorder: true } },
{ multi: true }
)

Os documentos resultantes na coleção são os seguintes:

[
{
"_id" : 1,
"item" : "ABC123",
"stock" : 5,
"info" : {
"publisher" : "2222",
"pages" : 430
},
"ratings" : [ { "by" : "ijk", "rating" : 4 }, { "by" : "xyz", "rating" : 3 } ],
"reorder" : true
}
{
"_id" : 2,
"item" : "XYZ123",
"stock" : 10,
"info" : { "publisher" : "2255", "pages" : 150 },
"tags" : [ "baking", "cooking" ],
"reorder" : true
}
]

Esta operação corresponde à seguinte declaração SQL:

UPDATE books
SET reorder=true
WHERE stock <= 10

Não é possível especificar multi: true ao realizar uma substituição e o documento de atualização contém apenas expressões field:value.

Dica

Veja também:

Quando você especifica a opção upsert: true:

  • Se o(s) documento(s) corresponder(em) aos critérios de query, db.collection.update() executará uma atualização.

  • Se nenhum documento corresponder aos critérios de query, db.collection.update() insere um único documento.

    Observação

    Se vários upserts idênticos forem emitidos aproximadamente ao mesmo tempo, é possível que update() usado com upsert: true crie documentos duplicados. Consulte Upsert com valores duplicados para obter mais informações.

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.update() em uma coleção fragmentada, consulte Coleções fragmentadas.

As abas a seguir mostram uma variedade de usos do modificador upsert com update()..

Se nenhum documento corresponder aos critérios de query e o parâmetro <update> for um documento de substituição (ou seja, contiver somente pares de campo e valor), a atualização inserirá um novo documento com os campos e valores do documento de substituição.

  • Se você especificar um campo _id no parâmetro de query ou documento de substituição, o MongoDB utilizará esse campo _id no documento inserido.

  • Se você não especificar um campo _id no parâmetro de query ou no documento de substituição, o MongoDB adicionará o campo _id com um valor de ObjectId gerado aleatoriamente.

    Você não pode especificar diferentes valores de campo _id no parâmetro de query e documento de substituição. Se o fizer, a operação apresentará erros.

Por exemplo, a atualização a seguir define a opção upsert como true:

db.books.update(
{ item: "ZZZ135" }, // Query parameter
{ $set:
{
item: "ZZZ135", stock: 5, tags: [ "database" ] // Replacement document
}
},
{ upsert: true } // Options
)

Se nenhum documento corresponder ao parâmetro <query>, a operação de atualização inserirá um documento somente com o documento de substituição. Como nenhum campo _id foi especificado no documento de substituição ou documento de query, a operação cria um novo ObjectId exclusivo para o campo _id do novo documento. Você pode visualizar upsert refletido no WriteResult da operação:

WriteResult({
"nMatched" : 0,
"nUpserted" : 1,
"nModified" : 0,
"_id" : ObjectId("5da78973835b2f1c75347a83")
})

A operação insere o seguinte documento na coleção books (seu valor de ObjectId será diferente):

{
"_id" : ObjectId("5da78973835b2f1c75347a83"),
"item" : "ZZZ135",
"stock" : 5,
"tags" : [ "database" ]
}

Se nenhum documento corresponder aos critérios de query e o parâmetro <update> for um documento com expressão de operador de atualização, a operação criará um documento base a partir das cláusulas de igualdade no parâmetro <query> e aplicará as expressão do parâmetro <update>.

As operações de comparação do <query> não serão incluídas no novo documento. Se o novo documento não incluir o campo _id , o MongoDB adicionará o campo _id com um valor ObjectId .

Por exemplo, a atualização a seguir define a opção upsert como true:

db.books.update(
{ item: "BLP921" }, // Query parameter
{ // Update document
$set: { reorder: false },
$setOnInsert: { stock: 10 }
},
{ upsert: true } // Options
)

Se nenhum documento corresponder à condição de query, a operação inserirá o seguinte documento (seu valor ObjectId será diferente):

{
"_id" : ObjectId("5da79019835b2f1c75348a0a"),
"item" : "BLP921",
"reorder" : false,
"stock" : 10
}

Dica

Veja também:

Se o parâmetro <update> for um pipeline de agregação, a atualização criará um documento base a partir das cláusulas de igualdade no parâmetro <query> e, em seguida, aplicará o pipeline ao documento para criar o documento a ser inserido. Se o novo documento não incluir o campo _id, o MongoDB adicionará o campo _id com um valor ObjectId.

Por exemplo, a seguinte operação upsert: true especifica um pipeline de agregação que usa

  • o estágio $replaceRoot que pode proporcionar um comportamento semelhante ao de uma expressão do operador de atualização $setOnInsert,

  • o estágio $set, que pode fornecer um comportamento semelhante à expressão do operador de atualização $set,

  • a variável de agregação NOW, que produz a data e hora atual e pode fornecer um comportamento semelhante à expressão do operador de atualização $currentDate.

db.books.update(
{ item: "MRQ014", ratings: [2, 5, 3] }, // Query parameter
[ // Aggregation pipeline
{ $replaceRoot: { newRoot: { $mergeObjects: [ { stock: 0 }, "$$ROOT" ] } } },
{ $set: { avgRating: { $avg: "$ratings" }, tags: [ "fiction", "murder" ], lastModified: "$$NOW" } }
],
{ upsert: true } // Options
)

Se nenhum documento corresponder ao parâmetro <query>, a operação insere o seguinte documento na coleção books (seu valor de ObjectId será diferente):

{
"_id" : ObjectId("5e2921e0b4c550aad59d1ba9"),
"stock" : 0,
"item" : "MRQ014",
"ratings" : [ 2, 5, 3 ],
"avgRating" : 3.3333333333333335,
"tags" : [ "fiction", "murder" ],
"lastModified" : ISODate("2020-01-23T04:32:32.951Z")
}

Dica

Veja também:

Para obter exemplos adicionais de atualizações usando pipelines de agregação, consulte Atualizar com pipeline de agregação.

A partir de mongosh, insira os seguintes documentos em uma coleção books:

db.books.insertMany( [
{
_id: 5,
item: "RQM909",
stock: 18,
info: { publisher: "0000", pages: 170 },
reorder: true
},
{
_id: 6,
item: "EFG222",
stock: 15,
info: { publisher: "1111", pages: 72 },
reorder: true
}
] )

A operação a seguir especifica a opção multi e a opção upsert. Se houver documentos correspondentes, a operação atualizará todos os documentos correspondentes. Se não houver documentos correspondentes, a operação inserirá um novo documento.

db.books.update(
{ stock: { $gte: 10 } }, // Query parameter
{ // Update document
$set: { reorder: false, tags: [ "literature", "translated" ] }
},
{ upsert: true, multi: true } // Options
)

A operação atualiza todos os documentos correspondentes e resulta no seguinte:

{
"_id" : 5,
"item" : "RQM909",
"stock" : 18,
"info" : { "publisher" : "0000", "pages" : 170 },
"reorder" : false,
"tags" : [ "literature", "translated" ]
}
{
"_id" : 6,
"item" : "EFG222",
"stock" : 15,
"info" : { "publisher" : "1111", "pages" : 72 },
"reorder" : false,
"tags" : [ "literature", "translated" ]
}

Se a coleção não tivesse nenhum documento correspondente, a operação resultaria na inserção de um único documento usando os campos das especificações <query> e <update>. Por exemplo, considere a seguinte operação:

db.books.update(
{ "info.publisher": "Self-Published" }, // Query parameter
{ // Update document
$set: { reorder: false, tags: [ "literature", "hardcover" ], stock: 25 }
},
{ upsert: true, multi: true } // Options
)

A operação insere o seguinte documento na coleção books (seu valor de ObjectId será diferente):

{
"_id" : ObjectId("5db337934f670d584b6ca8e0"),
"info" : { "publisher" : "Self-Published" },
"reorder" : false,
"stock" : 25,
"tags" : [ "literature", "hardcover" ]
}

Quando você executar um update() com upsert: true e a query não corresponder a nenhum documento existente, o MongoDB irá se recusar a inserir um novo documento se a query especificar condições no campo _id usando notação de ponto.

Essa restrição garante que a ordem dos campos inseridos no documento _id seja bem definida e não esteja vinculada à ordem especificada na consulta.

Se você tentar inserir um documento dessa maneira, o MongoDB gerará um erro. Por exemplo, considere a seguinte operação de atualização. Como a operação de atualização especifica upsert:true e a query especifica as condições no campo _id usando a notação de ponto, a atualização resultará em um erro ao criar o documento a ser inserido.

db.collection.update(
{ "_id.name": "Robert Frost", "_id.uid": 0 }, // Query parameter
{ $set:
{
"categories": [ "poet", "playwright" ] // Replacement document
}
},
{ upsert: true } // Options
)

O WriteResult da operação retorna o seguinte erro:

WriteResult({
"nMatched" : 0,
"nUpserted" : 0,
"nModified" : 0,
"writeError" : {
"code" : 111,
"errmsg" : "field at '_id' must be exactly specified, field at sub-path '_id.name'found"
}
})

Dica

Veja também:

Os upserts podem criar documentos duplicados, a menos que haja um índice único para evitar duplicatas.

Considere um exemplo em que nenhum documento com o nome Andy existe e vários clientes emitem o seguinte comando ao mesmo tempo:

db.people.update(
{ name: "Andy" },
{ $inc: { score: 1 } },
{
upsert: true,
multi: true
}
)

Se todas as operações update() terminarem a fase de query antes que qualquer cliente insira dados com êxito e não houver nenhum índice exclusivo no campo name, cada operação update() poderá resultar em uma inserção, criando vários documentos com name: Andy.

Um índice exclusivo no campo name garante que somente um documento seja criado. Com um índice único em vigor, as múltiplas operações update() agora apresentam o seguinte comportamento:

  • Exatamente uma operação update() inserirá com êxito um novo documento.

  • Outras operações update() atualizam o documento recém-inserido ou falham devido a uma colisão de chave exclusiva.

    Para que outras operações update() atualizem o documento recém-inserido, todas as seguintes condições devem ser atendidas:

    • A collection de destino tem um índice único que causaria um erro de chave duplicado.

    • A operação de atualização não é updateMany ou multi é false.

    • A condição de correspondência de atualização é:

      • Um único predicado de igualdade. Por exemplo { "fieldA" : "valueA" }

      • Um E lógico de predicados de igualdade. Por exemplo { "fieldA" : "valueA", "fieldB" : "valueB" }

    • O campo no predicado de igualdade correspondem ao campo no padrão de chave de índice único.

    • A operação de atualização não modifica nenhum campo no padrão de chave de índice único.

A tabela a seguir mostra exemplos de operações upsert que, quando ocorre uma colisão de chaves, resultam em uma atualização ou falha.

Padrão de chave de índice exclusivo
Operação de atualização
Resultado
{ name : 1 }
db.people.updateOne(
{ name: "Andy" },
{ $inc: { score: 1 } },
{ upsert: true }
)
O campo score do documento correspondente é incrementado em 1.
{ name : 1 }
db.people.updateOne(
{ name: { $ne: "Joe" } },
{ $set: { name: "Andy" } },
{ upsert: true }
)
A operação falha porque modifica o campo no padrão de chave de índice único (name).
{ name : 1 }
db.people.updateOne(
{ name: "Andy", email: "andy@xyz.com" },
{ $set: { active: false } },
{ upsert: true }
)
A operação falha porque os campos de predicados de igualdade (name, email) não correspondem ao campo chave de índice (name).

Dica

Veja também:

O método db.collection.update() pode aceitar um pipeline de agregação [ <stage1>, <stage2>, ... ] que especifica as modificações a serem realizadas. O pipeline pode consistir nas seguintes etapas:

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).

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 campo lastUpdate.

  • remova os campos commentsSemester1 e commentsSemester2 de todos os documentos da coleção.

db.members.update(
{ },
[
{ $set: { comments: [ "$commentsSemester1", "$commentsSemester2" ], lastUpdate: "$$NOW" } },
{ $unset: [ "commentsSemester1", "commentsSemester2" ] }
],
{ multi: true }
)

Observação

O $set e o $unset usados no pipeline referem-se aos estágios de aggregation $set e $unset, respectivamente, e não aos operadores de atualização $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 campos commentsSemester1 e commentsSemester2 e

  • define o campo lastUpdate para o valor da variável de agregação NOW. A variável de agregação NOW é 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 campos commentsSemester1 e commentsSemester2.

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" ] }

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.update(
{ },
[
{ $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"
} } } }
],
{ multi: true }
)

Observação

O $set usado no pipeline refere-se ao estágio de aggregation $set, e não aos operadores de atualização $set.

Primeira etapa

O estágio $set:

  • calcula um novo campo average com base na média do campo tests. 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ção NOW. A variável de agregação NOW é 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 campo grade com base no campo average 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:29:35.340Z"), "average" : 92, "grade" : "A" }
{ "_id" : 2, "tests" : [ 94, 88, 90 ], "lastUpdate" : ISODate("2020-01-24T17:29:35.340Z"), "average" : 90, "grade" : "A" }
{ "_id" : 3, "tests" : [ 70, 75, 82 ], "lastUpdate" : ISODate("2020-01-24T17:29:35.340Z"), "average" : 75, "grade" : "C" }

No documento de atualização, use o operador posicional filtrado $[<identifier>] para definir um identificador, que você então faz referência nos documentos de filtro de array. Você não pode ter um documento de filtro de array para um identificador se o identificador não estiver incluído no documento de atualização.

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

Você pode incluir o mesmo identificador várias vezes no documento de atualização; entretanto, para cada identificador distinto ($[identifier]) no documento de atualização, você deve especificar exatamente um documento de filtro de array correspondente. Ou seja, não é possível especificar vários documentos de filtro de array para o mesmo identificador. Por exemplo, se a instrução de atualização incluir o identificador x (possivelmente várias vezes), você não poderá especificar o seguinte para arrayFilters que inclui 2 documentos de filtro separados para x:

// INVALID
[
{ "x.a": { $gt: 85 } },
{ "x.b": { $gt: 80 } }
]

No entanto, você pode especificar condições compostas no mesmo identificador em um único documento de filtro, como nos exemplos a seguir:

// Example 1
[
{ $or: [{"x.a": {$gt: 85}}, {"x.b": {$gt: 80}}] }
]
// Example 2
[
{ $and: [{"x.a": {$gt: 85}}, {"x.b": {$gt: 80}}] }
]
// Example 3
[
{ "x.a": { $gt: 85 }, "x.b": { $gt: 80 } }
]

arrayFilters não está disponível para atualizações que usam um pipeline de agregação

Para atualizar todos os elementos de array que correspondem a um critério especificado, utilize o parâmetro arrayFilters.

No mongosh, crie uma coleção 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.update(
{ grades: { $gte: 100 } },
{ $set: { "grades.$[element]" : 100 } },
{
multi: true,
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 ] }

Você também pode usar o parâmetro arrayFilters para atualizar campos de documentos específicos em uma array de documentos.

No mongosh, crie uma coleção 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.update(
{ },
{ $set: { "grades.$[elem].mean" : 100 } },
{
multi: true,
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 }
]
}

No mongosh, crie uma coleção newStudents com os seguintes documentos:

db.newStudents.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 o seguinte índice na coleção:

db.newStudents.createIndex( { grade: 1 } )

A seguinte operação de atualização sugere explicitamente o uso do índice {grade: 1 }:

db.newStudents.update(
{ points: { $lte: 20 }, grade: "F" }, // Query parameter
{ $set: { comments1: "failed class" } }, // Update document
{ multi: true, hint: { grade: 1 } } // Options
)

Observação

Se você especificar um índice que não existe, a operação emitirá erros.

O comando de atualização retorna o seguinte:

WriteResult({ "nMatched" : 3, "nUpserted" : 0, "nModified" : 3 })

Para visualizar o índice utilizado, execute o explain na operação:

db.newStudents.explain().update(
{ "points": { $lte: 20 }, "grade": "F" },
{ $set: { "comments1": "failed class" } },
{ multi: true, hint: { grade: 1 } }
)

O db.collection.explain().update() não modifica os documentos.

Novidades na versão 5.0.

Para definir variáveis que você pode acessar em outro lugar no comando, use a opção let .

Observação

Para filtrar resultados usando uma variável, você deve acessar a variável dentro do operador $expr.

Criar uma coleção cakeFlavors:

db.cakeFlavors.insertMany( [
{ _id: 1, flavor: "chocolate" },
{ _id: 2, flavor: "strawberry" },
{ _id: 3, flavor: "cherry" }
] )

O exemplo seguinte define targetFlavor e newFlavor variáveis no let e utiliza as variáveis para alterar o sabor do bolo de cereja para laranja:

db.cakeFlavors.update(
{ $expr: { $eq: [ "$flavor", "$$targetFlavor" ] } },
[ { $set: { flavor: "$$newFlavor" } } ],
{ let : { targetFlavor: "cherry", newFlavor: "orange" } }
)

A operação a seguir para um conjunto de réplicas especifica uma preocupação de gravação de w: 2 com uma wtimeout de 5000 milissegundos. Essa operação retorna depois que a gravação se propaga para o primário e um secundário ou expira após 5 segundos.

db.books.update(
{ stock: { $lte: 10 } },
{ $set: { reorder: true } },
{
multi: true,
writeConcern: { w: 2, wtimeout: 5000 }
}
)

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:

collation: {
locale: <string>,
caseLevel: <boolean>,
caseFirst: <string>,
strength: <int>,
numericOrdering: <boolean>,
alternate: <string>,
maxVariable: <string>,
backwards: <boolean>
}

Ao especificar agrupamento, o campo locale é obrigatório; todos os outros campos de agrupamento são opcionais. Para obter descrições dos campos, consulte Documento de agrupamento.

Se o agrupamento não for especificado, mas a coleção tiver um agrupamento padrão (consulte db.createCollection()), a operação usará o agrupamento especificado para a coleção.

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.

No mongosh, crie uma coleção denominada myColl com os seguintes documentos:

db.myColl.insertMany( [
{ _id: 1, category: "café", status: "A" },
{ _id: 2, category: "cafe", status: "a" },
{ _id: 3, category: "cafE", status: "a" }
] )

A operação a seguir inclui a opção de agrupamento e define multi como true para atualizar todos os documentos correspondentes:

db.myColl.update(
{ category: "cafe" },
{ $set: { status: "Updated" } },
{
collation: { locale: "fr", strength: 1 },
multi: true
}
)

O resultado de gravação da operação retorna o seguinte documento, indicando que todos os três documentos na coleção foram atualizados:

WriteResult({ "nMatched" : 3, "nUpserted" : 0, "nModified" : 3 })

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

{ "_id" : 1, "category" : "café", "status" : "Updated" }
{ "_id" : 2, "category" : "cafe", "status" : "Updated" }
{ "_id" : 3, "category" : "cafE", "status" : "Updated" }

O método db.collection.update() retorna um objeto WriteResult() que contém o status da operação. Após o sucesso, o objeto WriteResult() contém o número de documentos que corresponderam à condição de query, o número de documentos inseridos pela atualização e o número de documentos modificados:

WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

Se o método db.collection.update() encontrar erros de preocupação de gravação, os resultados incluirão o campo WriteResult.writeConcernError:

WriteResult({
"nMatched" : 1,
"nUpserted" : 0,
"nModified" : 1,
"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 WriteResult.writeConcernError.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.

Se o método db.collection.update() encontrar um erro que não seja preocupação de gravação, os resultados incluirão o campo WriteResult.writeError:

WriteResult({
"nMatched" : 0,
"nUpserted" : 0,
"nModified" : 0,
"writeError" : {
"code" : 7,
"errmsg" : "could not contact primary for replica set shard-a"
}
})

Dica

Veja também:

Voltar

db.collection.unhideIndex