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

db.collection.updateOne()

Nesta página

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

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:

C#Java SyncNode.jsPyMongoCC++GoJava RSKotlin CoroutineKotlin SyncPHPMongoidRustScala
db.collection.updateOne(filter, update, options)

Atualiza um único documento dentro da coleção com base no filtro.

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

O método updateOne() tem a seguinte sintaxe:

db.collection.updateOne(
<filter>,
<update>,
{
upsert: <boolean>,
writeConcern: <document>,
collation: <document>,
arrayFilters: [ <filterdocument1>, ... ],
hint: <document|string>,
let: <document>
}
)

O método db.collection.updateOne() 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.

Especifique um documento vazio { } para atualizar o primeiro documento retornado na coleção.

documento ou pipeline

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

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

Para mais informações, consulte Atualize com um pipeline de agregação.

Para atualizar com um documento de substituição, consulte db.collection.replaceOne().

upsert
booleano

Opcional. Quando true, updateOne() ou:

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

  • Atualiza um único documento que corresponda a filter.

Para evitar várias atualizações, certifique-se de que os campos filter sejam indexados de forma exclusiva.

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

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:

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.

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 $[<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 } }
]

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

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

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

{
<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 ver um exemplo completo com let e variáveis, consulte Atualizar com variáveis let.

O método retorna um documento que contém:

  • matchedCount contendo o número de documentos correspondentes

  • modifiedCount contendo o número de documentos modificados

  • upsertedId contendo o _id para o documento atualizado

  • upsertedCount contendo o número de documentos upserted

  • Um valor booleano acknowledged como true se a operação for executada com preocupação de gravaçãorefer ou false se a preocupação de gravação estiver desativada

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.

db.collection.updateOne() encontra o primeiro documento que corresponde ao filtro e aplica as modificações de atualização especificadas.

Nas especificações de atualização, o método db.collection.updateOne() pode aceitar um documento que contém somente expressões do operador de atualização.

Por exemplo:

db.collection.updateOne(
<query>,
{ $set: { status: "D" }, $inc: { quantity: 2 } },
...
)

O método db.collection.updateOne() 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).

Por exemplo:

db.collection.updateOne(
<query>,
[
{ $set: { status: "Modified", comments: [ "$misc1", "$misc2" ] } },
{ $unset: [ "misc1", "misc2" ] }
]
...
)

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.

Para obter exemplos, consulte Atualizar com pipeline de agregação.

Se upsert: true e nenhum documento corresponder ao filter, db.collection.updateOne() cria um novo documento com base nos critérios de filter e modificações de update. Consulte Atualização com upsert.

Se você especificar upsert: true em uma coleção fragmentada, você deverá incluir a chave de shard completa no filtro. Para comportamento adicional db.collection.updateOne() em uma coleção fragmentada, consulte Coleções fragmentadas.

Se uma operação de atualização alterar o tamanho do documento, a operação falhará.

Para usar db.collection.updateOne() em uma coleção fragmentada:

  • Se você não especificar upsert: true, deverá incluir uma correspondência exata no campo _id ou direcionar um único fragmento (por exemplo, incluindo a chave de fragmento no filtro).

  • Se você especificar upsert: true, o filtro deverá incluir a chave de fragmento.

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.

Aviso

Os documentos em coleções fragmentadas podem não ter os campos chave de fragmentado. Tome cuidado para evitar remover acidentalmente a chave de fragmento ao alterar o valor dela em um documento.

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

  • Você deve executar em um mongos. Não emita a operação diretamente no fragmento.

  • Você deve executar em uma transação ou como uma gravação repetível.

  • Você deve incluir um filtro de igualdade na chave de fragmento completa.

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.updateOne() 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
  • Requer filtro de igualdade na chave de fragmento completa se upsert: true.

Para definir um valor diferente de null

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:

updateOne() não é compatível com db.collection.explain().

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

Dica

Veja também:

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.updateOne() conseguir atualizar um documento, ela adicionará uma entrada no oplog (log de operações). Se a operação falhar ou não encontrar um documento para atualizar, ela não adicionará uma entrada no oplog.

A coleção restaurant contém os seguintes documentos:

{ "_id" : 1, "name" : "Central Perk Cafe", "Borough" : "Manhattan" },
{ "_id" : 2, "name" : "Rock A Feller Bar and Grill", "Borough" : "Queens", "violations" : 2 },
{ "_id" : 3, "name" : "Empire State Pub", "Borough" : "Brooklyn", "violations" : 0 }

A operação a seguir atualiza um único documento onde name: "Central Perk Cafe" com o campo violations:

try {
db.restaurant.updateOne(
{ "name" : "Central Perk Cafe" },
{ $set: { "violations" : 3 } }
);
} catch (e) {
print(e);
}

A operação retorna:

{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }

Se nenhuma correspondência for encontrada, a operação retornará:

{ "acknowledged" : true, "matchedCount" : 0, "modifiedCount" : 0 }

A configuração upsert: true inseriria o documento se nenhuma correspondência fosse encontrada. Consulte Atualize com upsert

O db.collection.updateOne() pode utilizar um pipeline de agregação para a atualização. 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).

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, "student" : "Elizabeth", "points" : 60, "commentsSemester1" : "well behaved", "commentsSemester2" : "needs improvement", "lastUpdate" : ISODate("2019-01-01T00:00:00Z") }
] )

Suponha que, em vez de campos commentsSemester1 e commentsSemester2 separados no primeiro documento, você deseja uni-los em um campo comments, como o segundo documento. 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.

Certifique-se de que o filtro no comando de atualização direcione para um documento exclusivo. O campo id no código abaixo é um exemplo desse filtro:

db.students.updateOne(
{ _id: 1 },
[
{ $set: { status: "Modified", comments: [ "$commentsSemester1", "$commentsSemester2" ], lastUpdate: "$$NOW" } },
{ $unset: [ "commentsSemester1", "commentsSemester2" ] }
]
)

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 misc1 e misc2 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" : 2, "student" : "Elizabeth", "status" : "Modified", "points" : 60, "lastUpdate" : ISODate("2020-01-23T05:11:45.784Z"), "comments" : [ "well behaved", "needs improvement" ] }
{ _id: 1, student: 'Skye', points: 75, commentsSemester1: 'great at math', commentsSemester2: 'loses temper', lastUpdate: ISODate("2019-01-01T00:00:00.000Z") }

Observe que depois de introduzir uma classificação, somente o primeiro documento encontrado na ordem de classificação é modificado e os documentos restantes permanecem intocados.

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 ], "average" : 92, "grade" : "A", "lastUpdate" : ISODate("2020-01-23T05:18:40.013Z") },
{ "_id" : 2, "tests" : [ 94, 88, 90 ], "average" : 91, "grade" : "A", "lastUpdate" : ISODate("2020-01-23T05:18:40.013Z") },
{ "_id" : 3, "tests" : [ 70, 75, 82 ], "lastUpdate" : ISODate("2019-01-01T00:00:00Z") }
] )

O _id: 3 do terceiro documento, não possui os campos average e grade. Usando uma pipeline de agregação, você pode atualizar o documento com a média calculada e a nota por letra.

db.students3.updateOne(
{ _id: 3 },
[
{ $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

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 ], "average" : 92, "grade" : "A", "lastUpdate" : ISODate("2020-01-23T05:18:40.013Z") }
{ "_id" : 2, "tests" : [ 94, 88, 90 ], "average" : 91, "grade" : "A", "lastUpdate" : ISODate("2020-01-23T05:18:40.013Z") }
{ "_id" : 3, "tests" : [ 70, 75, 82 ], "lastUpdate" : ISODate("2020-01-24T17:33:30.674Z"), "average" : 75, "grade" : "C" }

A coleção restaurant contém os seguintes documentos:

{ "_id" : 1, "name" : "Central Perk Cafe", "Borough" : "Manhattan", "violations" : 3 },
{ "_id" : 2, "name" : "Rock A Feller Bar and Grill", "Borough" : "Queens", "violations" : 2 },
{ "_id" : 3, "name" : "Empire State Pub", "Borough" : "Brooklyn", "violations" : "0" }

A operação a seguir tenta atualizar o documento com name : "Pizza Rat's Pizzaria", enquanto upsert: true:

try {
db.restaurant.updateOne(
{ "name" : "Pizza Rat's Pizzaria" },
{ $set: {"_id" : 4, "violations" : 7, "borough" : "Manhattan" } },
{ upsert: true }
);
} catch (e) {
print(e);
}

Como upsert:true o documento é inserted com base nos critérios filter e update. A operação retorna:

{
"acknowledged" : true,
"matchedCount" : 0,
"modifiedCount" : 0,
"upsertedId" : 4,
"upsertedCount": 1
}

A coleção agora contém os seguintes documentos:

{ "_id" : 1, "name" : "Central Perk Cafe", "Borough" : "Manhattan", "violations" : 3 },
{ "_id" : 2, "name" : "Rock A Feller Bar and Grill", "Borough" : "Queens", "violations" : 2 },
{ "_id" : 3, "name" : "Empire State Pub", "Borough" : "Brooklyn", "violations" : 4 },
{ "_id" : 4, "name" : "Pizza Rat's Pizzaria", "Borough" : "Manhattan", "violations" : 7 }

O campo name foi preenchido usando os critérios filter, enquanto os operadores update foram usados para criar o restante do documento.

A operação a seguir atualiza o primeiro documento com violations que é maior que 10:

try {
db.restaurant.updateOne(
{ "violations" : { $gt: 10} },
{ $set: { "Closed" : true } },
{ upsert: true }
);
} catch (e) {
print(e);
}

A operação retorna:

{
"acknowledged" : true,
"matchedCount" : 0,
"modifiedCount" : 0,
"upsertedId" : ObjectId("56310c3c0c5cbb6031cafaea")
}

A coleção agora contém os seguintes documentos:

{ "_id" : 1, "name" : "Central Perk Cafe", "Borough" : "Manhattan", "violations" : 3 },
{ "_id" : 2, "name" : "Rock A Feller Bar and Grill", "Borough" : "Queens", "violations" : 2 },
{ "_id" : 3, "name" : "Empire State Pub", "Borough" : "Brooklyn", "violations" : 4 },
{ "_id" : 4, "name" : "Pizza Rat's Pizzaria", "Borough" : "Manhattan", "grade" : 7 }
{ "_id" : ObjectId("56310c3c0c5cbb6031cafaea"), "Closed" : true }

Como nenhum documento correspondeu ao filtro e upsert era true, updateOne() inseriu o documento com um _id gerado e apenas o critério update.

Dado um conjunto de réplicas de três nós, a operação a seguir especifica um w de majority, wtimeout de 100:

try {
db.restaurant.updateOne(
{ "name" : "Pizza Rat's Pizzaria" },
{ $inc: { "violations" : 3}, $set: { "Closed" : true } },
{ w: "majority", wtimeout: 100 }
);
} catch (e) {
print(e);
}

Se o primário e pelo menos um secundário reconhecerem cada operação de gravação dentro de 100 milissegundos, ele retornará:

{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }

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.

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.updateOne(
{ category: "cafe" },
{ $set: { status: "Updated" } },
{ collation: { locale: "fr", strength: 1 } }
);

Ao atualizar um campo de array, você pode especificar arrayFilters que determinam quais elementos de array atualizar.

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 modificar todos os elementos maiores ou iguais a 100 na array grades, use o operador posicional filtrado $[<identifier>] com a opção arrayFilters no método db.collection.updateOne():

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

A operação atualiza o campo grades de um único documento e, após a operação, a coleção tem os seguintes documentos:

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

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 na array grades onde a nota é maior ou igual a 85, use o operador posicional filtrado $[<identifier>] com o arrayFilters no método db.collection.updateOne():

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

A operação atualiza a array de um único documento e após a operação, a coleção possui 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" : 75, "std" : 6 },
{ "grade" : 87, "mean" : 90, "std" : 3 },
{ "grade" : 85, "mean" : 85, "std" : 4 }
]
}

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 } )
db.students.createIndex( { points: 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.updateOne(
{ "points": { $lte: 20 }, "grade": "F" },
{ $set: { "comments1": "failed class" } },
{ hint: { grade: 1 } }
)

O comando de atualização retorna o seguinte:

{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }

Observação

Embora 3 documentos correspondam aos critérios da atualização, updateOne apenas modifica o primeiro documento que encontra. Portanto, embora todos os alunos Richard, Ronan e Adam atendam aos critérios, apenas Richard será atualizado.

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

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

Dica

Veja também:

Para atualizar vários documentos, consulte db.collection.updateMany().

Voltar

db.collection.updateMany