update
Definição
update
O comando
update
modifica documentos em uma coleção. Um único comandoupdate
pode conter várias declarações de atualização.Dica
No
mongosh
, este comando também pode ser executado através dos métodos auxiliaresupdateOne()
,updateMany()
,replaceOne()
,findOneAndReplace()
efindOneAndUpdate()
.Os métodos auxiliares são práticos para os usuários
mongosh
, mas podem não retornar o mesmo nível de informações que os comandos do banco de dados. Nos casos em que a praticidade não for necessária ou os campos de retorno adicionais forem necessários, use o comando de banco de dados.
Sintaxe
Alterado na versão 5.0.
O comando update
tem a seguinte sintaxe:
db.runCommand( { update: <collection>, updates: [ { q: <query>, u: <document or pipeline>, c: <document>, // Added in MongoDB 5.0 upsert: <boolean>, multi: <boolean>, collation: <document>, arrayFilters: <array>, hint: <document|string> }, ... ], ordered: <boolean>, maxTimeMS: <integer>, writeConcern: { <write concern> }, bypassDocumentValidation: <boolean>, comment: <any>, let: <document> // Added in MongoDB 5.0 } )
Campos de comando
O comando utiliza os seguintes campos:
Campo | Tipo | Descrição | |||||
---|---|---|---|---|---|---|---|
update | string | O nome da coleção de destino. | |||||
updates | array | Uma array de uma ou mais declarações de atualização para executar na coleção denominada. Para obter detalhes sobre as declarações de atualização, consulte Declarações de atualização. | |||||
ordered | booleano | Opcional. Se true , então quando uma declaração de atualização falhar, retorne sem executar as declarações de atualização restantes. Se false , então quando uma atualização falhar, continue com as declarações de atualização restantes, se houver. O padrão é true . | |||||
maxTimeMS | número inteiro não negativo | Opcional. Especifica um limite de tempo em milissegundos. Se você não especificar um valor para O MongoDB encerra as operações que excedem o limite de tempo alocado usando o mesmo mecanismo de | |||||
writeConcern | documento | Opcional. Um documento que expressa a preocupação de gravação do comando 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. | |||||
bypassDocumentValidation | booleano | Opcional. Permite que update ignore a validação do documento durante a operação. Isso permite atualizar documentos que não atendem aos requisitos de validação. | |||||
comment | qualquer | Opcional. Um comentário fornecido pelo usuário para anexar a este comando. Depois de definido, esse comentário aparece junto com os registros desse comando nos seguintes locais:
Um comentário pode ser qualquer tipo BSON válido (string, inteiro, objeto, array etc). | |||||
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 obter um exemplo completo, consulte Uso de variáveis na opção Novidades na versão 5.0. |
Atualizar declarações
Cada elemento de array updates
é um documento de instrução de atualização. Cada documento contém os seguintes campos:
Campo | Tipo | Descrição | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
documento | A consulta que corresponde aos documentos a serem atualizados. Use os mesmos seletores de consulta usados no método | |||||||||||||||||||
documento ou pipeline | As modificações a serem aplicadas. O valor pode ser:
Para obter detalhes, consulte Comportamento. | |||||||||||||||||||
documento | Opcional. Você pode especificar 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 ( ObservaçãoPara usar uma variável para filtrar os resultados, você deve acessar a variável dentro do operador Para obter um exemplo completo usando Novidades na versão 5.0. | |||||||||||||||||||
booleano | Opcional. Quando
Se Para evitar várias upserts, certifique-se de que o(s) campo(s) de O padrão é | |||||||||||||||||||
multi | booleano | Opcional. Se Ao atualizar vários documentos, se um único documento não for atualizado, outros documentos não serão atualizados. Consulte Falhas de várias atualizações para obter mais detalhes sobre esse comportamento. | ||||||||||||||||||
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 ObservaçãoO 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 |
Devoluções
O comando retorna um documento que contém o status da operação. Por exemplo:
{ "ok" : 1, "nModified" : 0, "n" : 1, "upserted" : [ { "index" : 0, "_id" : ObjectId("52ccb2118908ccd753d65882") } ] }
Para obter detalhes sobre os campos de saída, consulte Saída.
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(ões) especificada(s).
A função embutida readWrite
fornece os privilégios exigidos.
Comportamento
Atualizar com um Documento de Expressões do Operador de Atualização
O campo de instrução de atualização u pode aceitar um documento que contenha apenas expressões de operador de atualização. Por exemplo:
updates: [ { q: <query>, u: { $set: { status: "D" }, $inc: { quantity: 2 } }, ... }, ... ]
Em seguida, o comando update
atualiza somente os campos correspondentes no documento.
Atualizar com um documento de substituição
O campo u da declaração de atualização pode aceitar um documento de substituição, ou seja, o documento contém apenas expressões field:value
. Por exemplo:
updates: [ { q: <query>, u: { status: "D", quantity: 4 }, ... }, ... ]
Em seguida, o comando update
substitui o documento correspondente pelo documento de atualização. O comando update
só pode substituir um único documento correspondente; ou seja, o campo multi
não pode ser true
. O comando update
não substitui o valor _id
.
Falhas em múltiplas atualizações
Se um único documento não for atualizado em um comando de atualização com o parâmetro multi
definido como true
, nenhum outro documento será atualizado como parte desse comando.
Por exemplo, criar uma coleção members
com os seguintes documentos:
db.members.insertMany( [ { "_id" : 1, "member" : "Taylor", "status" : "pending", "points" : 1}, { "_id" : 2, "member" : "Alexis", "status" : "enrolled", "points" : 59}, { "_id" : 3, "member" : "Elizabeth", "status" : "enrolled", "points" : 34} ] )
A operação seguinte cria um validador de documento na coleção members
com uma regra que o valor points
não pode ser igual a 60
.
db.runCommand( { collMod: "members", validator: { points: { $ne: 60 } } } )
Este comando de atualização aumenta o campo points
de cada documento em 1
.
db.runCommand( { update: "members", updates: [ { q: {}, u: { $inc: { points: 1 } }, multi: true } ] } )
Após executar o comando, a coleção contém os seguintes documentos:
{ _id: 1, member: 'Taylor', status: 'A', points: 2 } { _id: 2, member: 'Alexis', status: 'D', points: 59 } { _id: 3, member: 'Elizabeth', status: 'C', points: 34 }
O comando update atualizou o valor points
do primeiro documento, mas falhou ao atualizar o segundo documento devido à regra do validador de que o valor points
não pode ser igual 60
. O terceiro documento não foi atualizado porque nenhum outro documento foi atualizado após um erro de gravação.
Atualize com um pipeline de agregação.
O campo u da instrução de atualização 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:
updates: [ { q: <query>, u: [ { $set: { status: "Modified", comments: [ "$misc1", "$misc2" ] } }, { $unset: [ "misc1", "misc2" ] } ], ... }, ... ]
Observação
Para obter exemplos, consulte Atualizar com pipeline de agregação.
Upsert com índice exclusivo
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.runCommand( { update: "people", updates: [ { q: { name: "Andy" }, u: { $inc: { score: 1 } }, multi: true, upsert: 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
oumulti
é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 | ||||||
---|---|---|---|---|---|---|---|---|
|
| O campo score do documento correspondente é incrementado em 1. | ||||||
|
| A operação falha porque modifica o campo no padrão de chave de índice único ( name ). | ||||||
|
| A operação falha porque os campos de predicados de igualdade ( name , email ) não correspondem ao campo chave de índice (name ). |
Limites
Para cada elemento de atualização na array updates
, a soma da query e os tamanhos de atualização (ou seja, q
e u
) devem ser menores ou iguais ao tamanho máximo do documento BSON.
O número total de instruções de atualização na array updates
deve ser menor ou igual ao tamanho máximo em massa.
Validação do documento
O comando update
traz suporte para a opção bypassDocumentValidation
, que permite ignorar a validação do documento ao inserir ou atualizar documentos em uma coleção com regras de validação.
Coleções fragmentadas
upsert
em uma coleção fragmentada
Para usar update
com multi: false
em uma coleção fragmentada,
Se você não especificar upsert: true, o filtro q deverá incluir uma correspondência de igualdade no campo
_id
ou direcionar um único fragmento (por exemplo, incluindo a chave de fragmento).Se você especificar upsert: true, o filtro q deverá incluir uma correspondência de igualdade na 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
Substituir documento
Ao substituir um documento, o update
tenta direcionar um fragmento, primeiro usando o filtro de query. Se a operação não puder direcionar um único fragmento pelo filtro de consulta, ela tentará direcionar pelo documento de substituição.
Modificação da chave de fragmento
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 update
:
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 especificar
multi: false
.Você deve incluir um filtro de consulta de igualdade na chave de fragmento completa.
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.
Chave de fragmento ausente
Os documentos em coleções fragmentadas podem não ter os campos de chave de fragmento. Para usar 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 |
|
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:
Transações
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.
Inserção nas Transações
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.
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.
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.
Exemplos
Atualizar campos específicos de um documento
Use operadores de atualização para atualizar apenas os campos especificados de um documento.
Por exemplo, criar uma coleção members
com os seguintes documentos:
db.members.insertMany([ { _id: 1, member: "abc123", status: "Pending", points: 0, misc1: "note to self: confirm status", misc2: "Need to activate" }, { _id: 2, member: "xyz123", status: "D", points: 59, misc1: "reminder: ping me at 100pts", misc2: "Some random comment" }, ])
O comando a seguir usa os operadores de atualização $set
e $inc
para atualizar os campos status
e points
de um documento em que member
é igual a "abc123"
:
db.runCommand( { update: "members", updates: [ { q: { member: "abc123" }, u: { $set: { status: "A" }, $inc: { points: 1 } } } ], ordered: false, writeConcern: { w: "majority", wtimeout: 5000 } } )
Como <update>
documento não especifica o campo de multi
opcional, a atualização modifica apenas um documento, mesmo que mais de um documento corresponda à condição de correspondência de q
.
O documento retornado mostra que o comando encontrou e atualizou um único documento. O comando retorna:
{ "n" : 1, "nModified" : 1, "ok" : 1, <additional fields if run on a replica set/sharded cluster> }
Consulte Saída para detalhes.
Após o comando, a coleção contém os seguintes documentos:
{ "_id" : 1, "member" : "abc123", "status" : "A", "points" : 1, "misc1" : "note to self: confirm status", "misc2" : "Need to activate" } { "_id" : 2, "member" : "xyz123", "status" : "D", "points" : 59, "misc1" : "reminder: ping me at 100pts", "misc2" : "Some random comment" }
Atualizar campos específicos de vários documentos
Use operadores de atualização para atualizar apenas os campos especificados de um documento e inclua o campo multi
definido como true
na instrução update.
Por exemplo, uma coleção members
contém os seguintes documentos:
{ "_id" : 1, "member" : "abc123", "status" : "A", "points" : 1, "misc1" : "note to self: confirm status", "misc2" : "Need to activate" } { "_id" : 2, "member" : "xyz123", "status" : "D", "points" : 59, "misc1" : "reminder: ping me at 100pts", "misc2" : "Some random comment" }
O comando a seguir usa os operadores de atualização $set
e $inc
para modificar os campos status
e points
, respectivamente, de todos os documentos na coleção:
db.runCommand( { update: "members", updates: [ { q: { }, u: { $set: { status: "A" }, $inc: { points: 1 } }, multi: true } ], ordered: false, writeConcern: { w: "majority", wtimeout: 5000 } } )
A atualização modifica todos os documentos que correspondem à consulta especificada no campo q
, ou seja, a consulta vazia que corresponde a todos os documentos na coleção.
O documento retornado mostra que o comando encontrou e atualizou vários documentos. Para um conjunto de réplicas, o comando retorna:
{ "n" : 2, "nModified" : 2, "ok" : 1, <additional fields if run on a replica set/sharded cluster> }
Consulte Saída para detalhes.
Após o comando, a coleção contém os seguintes documentos:
{ "_id" : 1, "member" : "abc123", "status" : "A", "points" : 2, "misc1" : "note to self: confirm status", "misc2" : "Need to activate" } { "_id" : 2, "member" : "xyz123", "status" : "A", "points" : 60, "misc1" : "reminder: ping me at 100pts", "misc2" : "Some random comment" }
Atualização com aggregation pipeline
O comando update
pode usar 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
Os exemplos a seguir usam o aggregation pipeline para modificar um campo usando os valores de outros campos no documento.
Uma coleção members
contém os seguintes documentos:
{ "_id" : 1, "member" : "abc123", "status" : "A", "points" : 2, "misc1" : "note to self: confirm status", "misc2" : "Need to activate" } { "_id" : 2, "member" : "xyz123", "status" : "A", "points" : 60, "misc1" : "reminder: ping me at 100pts", "misc2" : "Some random comment" }
Suponha que, ao invés de separar os campos misc1
e misc2
, você deseja reuni-los em um novo campo comments
. A operação de atualização seguinte utiliza um pipeline de agregação para adicionar o novo campo comments
e remover os campos misc1
e misc2
para todos os documentos na coleção.
Primeiro, defina o campo
status
como"Modified"
e adicione um novo campocomments
que contenha o conteúdo atual de dois outros camposmisc1
emisc2
.Em segundo lugar, remova os campos
misc1
emisc2
.
db.runCommand( { update: "members", updates: [ { q: { }, u: [ { $set: { status: "Modified", comments: [ "$misc1", "$misc2" ] } }, { $unset: [ "misc1", "misc2" ] } ], multi: true } ], ordered: false, writeConcern: { w: "majority", wtimeout: 5000 } } )
Observação
O documento retornado mostra que o comando encontrou e atualizou vários documentos. O comando retorna:
{ "n" : 2, "nModified" : 2, "ok" : 1, <additional fields if run on a replica set/sharded cluster> }
Consulte Saída para detalhes.
Após o comando, a coleção contém os seguintes documentos:
{ "_id" : 1, "member" : "abc123", "status" : "Modified", "points" : 2, "comments" : [ "note to self: confirm status", "Need to activate" ] } { "_id" : 2, "member" : "xyz123", "status" : "Modified", "points" : 60, "comments" : [ "reminder: ping me at 100pts", "Some random comment" ] }
Exemplo 2
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.
db.students.insertMany( [ { "_id" : 1, "tests" : [ 95, 92, 90 ] }, { "_id" : 2, "tests" : [ 94, 88, 90 ] }, { "_id" : 3, "tests" : [ 70, 75, 82 ] } ] );
Usando um aggregation pipeline, você pode atualizar os documentos com a média calculada e a nota por letra.
db.runCommand( { update: "students", updates: [ { q: { }, u: [ { $set: { average : { $avg: "$tests" } } }, { $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 } ], ordered: false, writeConcern: { w: "majority", wtimeout: 5000 } } )
Observação
- Primeira etapa
- O estágio
$set
calcula um novo campoaverage
com base na média do campotests
. Consulte$avg
para obter mais informações sobre o operador de agregação$avg
. - 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
.
O documento retornado mostra que o comando encontrou e atualizou vários documentos. O comando retorna:
{ "n" : 3, "nModified" : 3, "ok" : 1, <additional fields if run on a replica set/sharded cluster> }
Após o comando, a coleção contém os seguintes documentos:
{ "_id" : 1, "tests" : [ 95, 92, 90 ], "average" : 92.33333333333333, "grade" : "A" } { "_id" : 2, "tests" : [ 94, 88, 90 ], "average" : 90.66666666666667, "grade" : "A" } { "_id" : 3, "tests" : [ 70, 75, 82 ], "average" : 75.66666666666667, "grade" : "C" }
Atualização em Massa
O seguinte exemplo executa múltiplas operações de atualização na coleção members
:
db.runCommand( { update: "members", updates: [ { q: { status: "P" }, u: { $set: { status: "D" } }, multi: true }, { q: { _id: 5 }, u: { _id: 5, name: "abc123", status: "A" }, upsert: true } ], ordered: false, writeConcern: { w: "majority", wtimeout: 5000 } } )
O documento retornado mostra que o comando modificou 10
documentos e inseriu um documento com o valor _id
5
. Consulte Saída para detalhes.
{ "ok" : 1, "nModified" : 10, "n" : 11, "upserted" : [ { "index" : 1, "_id" : 5 } ] }
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.runCommand({ update: "myColl", updates: [ { q: { category: "cafe", status: "a" }, u: { $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 determina quais elementos da array devem ser atualizados.
arrayFilters
Atualizar elementos que correspondem aos critérios
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 que são maiores ou iguais a 100
na array grades
, utilize o operador posicional filtrado $[<identifier>]
com a opção arrayFilters
:
db.runCommand( { update: "students", updates: [ { q: { grades: { $gte: 100 } }, u: { $set: { "grades.$[element]" : 100 } }, arrayFilters: [ { "element": { $gte: 100 } } ], multi: true} ] } )
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.runCommand({ update: "students2", updates: [ { q: { }, u: { $set: { "grades.$[elem].mean" : 100 } }, arrayFilters: [ { "elem.grade": { $gte: 85 } } ], multi: true } ] })
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 members
de amostra com os seguintes documentos:
db.members.insertMany([ { "_id" : 1, "member" : "abc123", "status" : "P", "points" : 0, "misc1" : null, "misc2" : null }, { "_id" : 2, "member" : "xyz123", "status" : "A", "points" : 60, "misc1" : "reminder: ping me at 100pts", "misc2" : "Some random comment" }, { "_id" : 3, "member" : "lmn123", "status" : "P", "points" : 0, "misc1" : null, "misc2" : null }, { "_id" : 4, "member" : "pqr123", "status" : "D", "points" : 20, "misc1" : "Deactivated", "misc2" : null }, { "_id" : 5, "member" : "ijk123", "status" : "P", "points" : 0, "misc1" : null, "misc2" : null }, { "_id" : 6, "member" : "cde123", "status" : "A", "points" : 86, "misc1" : "reminder: ping me at 100pts", "misc2" : "Some random comment" } ])
Crie os seguintes índices na coleção:
db.members.createIndex( { status: 1 } ) db.members.createIndex( { points: 1 } )
A seguinte operação de atualização sugere explicitamente o uso do índice {
status: 1 }
:
Observação
Se você especificar um índice que não existe, a operação emitirá erros.
db.runCommand({ update: "members", updates: [ { q: { "points": { $lte: 20 }, "status": "P" }, u: { $set: { "misc1": "Need to activate" } }, hint: { status: 1 }, multi: true } ] })
O comando de atualização retorna o seguinte:
{ "n" : 3, "nModified" : 3, "ok" : 1 }
Para visualizar o índice utilizado, execute o explain
na operação:
db.runCommand( { explain: { update: "members", updates: [ { q: { "points": { $lte: 20 }, "status": "P" }, u: { $set: { "misc1": "Need to activate" } }, hint: { status: 1 }, multi: true } ] }, verbosity: "queryPlanner" } )
O explain
não modifica os documentos.
Usar variáveis na let
opção ou no c
campo
Novidades na versão 5.0.
As variáveis podem ser definidas na opção let ou no campo c e acessadas no array updates
.
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.runCommand( { update: db.cakeFlavors.getName(), updates: [ { q: { $expr: { $eq: [ "$flavor", "$$targetFlavor" ] } }, u: [ { $set: { flavor: "$$newFlavor" } } ] } ], let : { targetFlavor: "cherry", newFlavor: "orange" } } )
O exemplo a seguir define targetFlavor
e newFlavor
variáveis em c
e usa as variáveis para alterar o sabor do bolo de chocolate para baunilha:
db.runCommand( { update: db.cakeFlavors.getName(), updates: [ { q: { $expr: { $eq: [ "$flavor", "$$targetFlavor" ] } }, u: [ { $set: { flavor: "$$newFlavor" } } ], c: { targetFlavor: "chocolate", newFlavor: "vanilla" } } ] } )
Saída
O documento devolvido contém um subconjunto dos seguintes campos:
update.n
Um comando
update
aceita uma array de atualizações de documentos, algumas das quais podem ser upserts. Para uma atualização,n
indica o número de documentos selecionados para a atualização. Para um upsert,n
é1
para o documento inserido. O servidor adiciona os valores den
para todas as atualizações e upserts e retorna o total comoupdate.n
.Se uma operação de atualização resultar em nenhuma alteração no documento, por exemplo, a expressão
$set
atualiza o valor para o valor atual,n
pode ser maior quenModified
.
update.nModified
O número de documentos atualizados. Se a operação de atualização não resultar em nenhuma alteração no documento, como definir o valor do campo com seu valor atual,
nModified
poderá ser menor quen
.
update.upserted
Uma array de documentos que contém informações para cada documento inserido através da atualização com
upsert: true
.Cada documento contém as seguintes informações:
update.writeErrors
Umo array de documentos que contém informações sobre qualquer erro encontrado durante a operação de atualização. o array
writeErrors
contém um documento de erro para cada instrução de atualização com erro.Cada documento de erro contém os seguintes campos:
update.writeConcernError
Documento que descreve o erro relacionado ao write concern e contém o campo:
update.writeConcernError.errInfo.writeConcern
O objeto de write concern usado para a operação correspondente. Para obter informações sobre os campos de objeto de write concern, consulte Especificação de write concern.
O objeto de write concern também pode conter o seguinte campo, indicando a origem da write concern:
update.writeConcernError.errInfo.writeConcern.provenance
Um valor de string que indica a origem do write concern (conhecido como write concern
provenance
). A tabela a seguir mostra os valores possíveis para este campo e sua significância:ProveniênciaDescriçãoclientSupplied
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. ConsultesetDefaultRWConcern
.getLastErrorDefaults
A preocupação de gravação originada do camposettings.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.
Além dos campos de retorno específicos de atualização mencionados acima, o db.runCommand()
inclui informações adicionais:
para conjuntos de réplicas:
optime
,electionId
,$clusterTime
eoperationTime
.para clusters fragmentados:
operationTime
e$clusterTime
.
Consulte Resposta db.runCommand para obter detalhes sobre esses campos.
A seguir, um exemplo de documento retornado para um comando update
bem-sucedido que executou um upsert:
{ "ok" : 1, "nModified" : 0, "n" : 1, "upserted" : [ { "index" : 0, "_id" : ObjectId("52ccb2118908ccd753d65882") } ] }
A seguir, um exemplo de documento retornado para uma atualização em lote envolvendo três comandos de atualização, em que um comando de atualização foi bem-sucedido e dois outros comandos de atualização encontraram erros:
{ "ok" : 1, "nModified" : 1, "n" : 1, "writeErrors" : [ { "index" : 1, "code" : 16837, "errmsg" : "The _id field cannot be changed from {_id: 1.0} to {_id: 5.0}." }, { "index" : 2, "code" : 16837, "errmsg" : "The _id field cannot be changed from {_id: 2.0} to {_id: 6.0}." }, ] }