MongoDB com drivers
Esta página documenta um método mongosh. Para ver o método equivalente em um driver MongoDB, consulte a página correspondente da sua linguagem de programação:
Definição
Compatibilidade
Esse método está disponível em implantações hospedadas nos seguintes ambientes:
MongoDB Atlas: o serviço totalmente gerenciado para implantações do MongoDB na nuvem
Observação
Este comando é aceito em todos os clusters do MongoDB Atlas. Para obter informações sobre o suporte do Atlas a todos os comandos, consulte Comandos não suportados.
MongoDB Enterprise: a versão autogerenciada e baseada em assinatura do MongoDB
MongoDB Community: uma versão com código disponível, de uso gratuito e autogerenciada do MongoDB
Sintaxe
O método updateMany() tem o seguinte formato:
db.collection.updateMany( <filter>, <update>, { upsert: <boolean>, writeConcern: <document>, collation: <document>, arrayFilters: [ <filterdocument1>, ... ], hint: <document|string>, let: <document>, maxTimeMS: <int>, bypassDocumentValidation: <boolean> } )
Parâmetros
O método updateMany() utiliza os seguintes parâmetros:
Parâmetro | Tipo | Descrição | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
documento | Os critérios de seleção para a atualização. Os mesmos seletores de consulta que no método Especifique um documento vazio | |||||||||||||||||||
documento ou pipeline | As modificações a serem aplicadas. Podem ser uma dos seguintes:
Para atualizar com um documento de substituição, consulte | |||||||||||||||||||
| booleano | Opcional. Quando,
Para evitar várias alterações, certifique-se de que os campos Padrão é | ||||||||||||||||||
| 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. | ||||||||||||||||||
| 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. | ||||||||||||||||||
| array | Opcional. Uma array de documentos de filtro que determina quais elementos da array modificar para uma operação de atualização em um campo da array. No documento de atualização, use o operador posicional filtrado O Você pode incluir o mesmo identificador várias vezes no documento de atualização; entretanto, para cada identificador distinto ( No entanto, você pode especificar condições compostas no mesmo identificador em um único documento de filtro, como nos exemplos a seguir: Para obter exemplos, consulte Especificar | ||||||||||||||||||
Documento ou string | Opcional. Um documento ou string que especifica o índice aser 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 um exemplo, consulte Especificar | |||||||||||||||||||
Documento | Opcional. Especifica um documento com uma lista de variáveis. Isso permite que você melhore a legibilidade do comando separando as variáveis do texto da query. A sintaxe do documento é: A variável é definida para o valor retornado pela expressão e não pode ser alterada posteriormente. Para acessar o valor de uma variável no comando, use o prefixo de dois cifrões ( Para usar uma variável para filtrar os resultados, você deve acessar a variável dentro do operador Para ver um exemplo completo com | |||||||||||||||||||
inteiro | Opcional. Especifica o limite de tempo, em milésimos de segundo, para que a operação de atualizar seja executada antes de atingir o tempo limite. | |||||||||||||||||||
booleano | Opcional. Permite que o |
Devoluções
O método retorna um documento que contém:
Um valor booleano
acknowledgedcomotruese a operação for executada com preocupação de gravaçãorefer oufalsese a preocupação de gravação estiver desativadamatchedCountcontendo o número de documentos correspondentesmodifiedCountcontendo o número de documentos modificadosupsertedIdcontendo o_idpara o documento atualizadoupsertedCountcontendo o número de documentos upserted
Controle de acesso
Em implantações executadas com authorization, o usuário deve ter acesso que inclua os seguintes privilégios:
updateação na(s) coleção(ões) especificada(s).findação na(s) coleção(ões) especificada(s).insertação na(s) coleção(s) especificada(s) se a operação resultar em um upsert.
A função embutida readWrite fornece os privilégios exigidos.
Comportamento
updateMany() encontra todos os documentos na collection que correspondem ao filter e aplica modificações especificadas pelo parâmetro update.
updateMany() modifica cada documento individualmente. Cada gravação de documento é uma operação atômica, mas updateMany() como um todo não é atômica. Se o seu caso de uso exigir atomicidade de gravações em vários documentos, use Transações.
Se uma única atualização de documento falhar, todas as atualizações de documento gravadas antes da falha serão mantidas, mas os documentos correspondentes restantes não serão atualizados. Para obter detalhes sobre esse comportamento, consulte Falhas em múltiplas atualizações.
Dica
Coleções Fragmentadas para obter mais informações sobre o updateMany() comportamento do em coleções fragmentadas.
Limitações
Upsert
Se upsert: true e nenhum documento corresponder a filter, db.collection.updateMany() cria um novo documento com base nos parâmetros filter e update.
Se você especificar upsert: true em uma coleção fragmentada, deverá incluir a chave de fragmento completa em filter. Para comportamento adicional do db.collection.updateMany(), consulte Coleções fragmentadas.
Atualizar com um Documento de Expressões do Operador de Atualização
Para a especificação de modificação, o método db.collection.updateMany() pode aceitar um documento que contém somente expressões de operador de atualização a serem executadas.
Por exemplo:
db.collection.updateMany( <query>, { $set: { status: "D" }, $inc: { quantity: 2 } }, ... )
Atualize com um pipeline de agregação.
O método db.collection.updateMany() pode aceitar um pipeline de agregação [ <stage1>, <stage2>, ... ] que especifica as modificações a serem realizadas. O pipeline pode consistir nas seguintes etapas:
$addFieldse seu alias$set$replaceRoote seu alias$replaceWith
O uso do aggregation pipeline permite uma instrução de atualização mais expressiva, como atualizações condicionais Express com base em valores de campo atuais ou atualização de um campo usando o valor de outro(s) campo(s).
Por exemplo:
db.collection.updateMany( <query>, [ { $set: { status: "Modified", comments: [ "$misc1", "$misc2" ] } }, { $unset: [ "misc1", "misc2" ] } ] ... )
Observação
Nesse pipeline, $set e $unset são estágios de agregação, diferentes dos operadores de atualização. Os estágios de agregação $set e $unset adicionam novos campos aos documentos e não modificam os valores dos campos existentes.
Para obter mais informações sobre os operadores de atualização, consulte $set e $unset.
Para obter exemplos, consulte Atualizar com pipeline de agregação.
Capped collections
Se uma operação de atualização alterar o tamanho do documento, a operação falhará.
Coleções de Time Series
O método updateMany() está disponível para coleções de séries temporais a partir do MongoDB 5.1.
Os comandos de atualização devem atender aos seguintes requisitos:
Você só pode combinar
metaFieldao valor do campo.Você só pode modificar o valor do campo
metaField.Seu documento de atualização só pode conter expressões de operador de atualização.
Seu comando de atualização não deve limitar o número de documentos a serem atualizados. Defina
multi: trueou use o métodoupdateMany().Seu comando de atualização não deve definir upsert: true.
Coleções fragmentadas
updateMany() exibe os seguintes comportamentos quando usado com coleções fragmentadas:
updateMany()operações que incluemupsert: truedevem incluir a chave de shard completa nofilter.Se você tentar executar
updateMany()durante uma Migração de faixa ou uma atualização de valor da chave de shard, a operação poderá perder documentos em alguns cenários. Para garantir que todos os documentos sejam atualizados, use atualizações idempotentes e execute novamente o comando até que nenhuma atualização seja aplicada. Para obter mais informações sobre atualizações idempotentesupdateMany()com, consulte Atualizações idempotentes.
Se
updateMany()for executado fora de uma transação, as operações que visam mais de um fragmento transmitirão a operação para todos os fragmentos no cluster.Se
updateMany()for executado dentro de uma transação, as operações que têm como alvo mais de um shard terão como alvo apenas os shards relevantes.
Explicabilidade
updateMany() não é compatível com db.collection.explain().
Transações
db.collection.updateMany() pode ser usado dentro de transações distribuídas.
Importante
Na maioria dos casos, uma transação distribuída incorre em um custo de desempenho maior do que as gravações de um único documento, e a disponibilidade de transações distribuídas não deve substituir o design eficaz do esquema. Em muitos cenários, o modelo de dados desnormalizado (documentos e arrays incorporados) continuará a ser ideal para seus dados e casos de uso. Ou seja, para muitos cenários, modelar seus dados adequadamente minimizará a necessidade de transações distribuídas.
Para considerações adicionais sobre o uso de transações (como limite de tempo de execução e limite de tamanho do oplog), consulte também Considerações de produção.
Inserção nas Transações
Você pode criar coleção e indexes dentro de uma transaction distribuída se a transaction não for uma transação de escrita de estilhaço cruzado.
db.collection.updateMany() com upsert: true pode ser executado em uma coleção existente ou em uma coleção inexistente. Se for executada em uma coleção inexistente, a operação cria a coleção.
Write concerns e transações
Não defina explicitamente a preocupação de gravação para a operação se for executada em uma transação. Para usar write concern com transações, consulte Transações e write concern.
Entradas de oplog
updateMany() adiciona uma entrada ao oplog (log de operações) para cada documento atualizado com êxito. Se nenhum documento for atualizado, o updateMany() não adicionará entradas ao oplog.
Exemplos
Os exemplos nesta página usam dados do conjunto de dados de amostra sample_mflix. Para obter detalhes sobre como carregar esse conjunto de dados em sua implantação autogerenciada do MongoDB , consulte Carregar o conjunto de dados de amostra. Se você fez modificações nos bancos de dados de amostra, talvez seja necessário descartar e recriar os bancos de dados para executar os exemplos nesta página.
Idempotent Updates
A sample_mflix.movies coleção contém filmes com classificações IMDB. Esta atualização idempotente faz as seguintes operações:
corresponde a todos os filmes com classificações de IMDB inferiores a 3.0
aumenta essas classificações em 0.5
definir um campo
ratingBoostedcomotrue
db.movies.updateMany( { "imdb.rating": { $lt: 3, $type: "number" }, ratingBoosted: { $ne: true } }, { $inc: { "imdb.rating": 0.5 }, $set: { ratingBoosted: true } } )
updateMany() modifica os documentos de filme correspondentes individualmente. As atualizações individuais de documento são operações atômicas, mas a operação updateMany() como um todo não é atômica.
Se a operação não atualizar todos os documentos correspondentes, você poderá executar novamente um comando idempotente com segurança até que nenhum documento adicional corresponda ao filtro especificado. Nesse caso, o campo imdb.rating de cada documento é atualizado somente uma vez, independentemente de quantas vezes seja repetido, pois o comando é idempotente.
Atualizar vários documentos
A coleção sample_mflix.movies contém filmes com um campo num_mflix_comments.
A operação a seguir encontra todos os filmes com mais de 100 comentários e adiciona um sinalizador popular a esses filmes:
db.movies.updateMany( { num_mflix_comments: { $gt: 100 } }, { $set: { "popular" : true } } )
Atualização com aggregation pipeline
O db.collection.updateMany() pode utilizar um pipeline de agregação para a atualização. O pipeline pode consistir nas seguintes etapas:
$addFieldse seu alias$set$replaceRoote seu alias$replaceWith
O uso do aggregation pipeline permite uma instrução de atualização mais expressiva, como atualizações condicionais Express com base em valores de campo atuais ou atualização de um campo usando o valor de outro(s) campo(s).
Exemplo 1: Atualização com Pipeline de Agregação Usando Campos Existentes
O exemplo a seguir usa o agregação pipeline para modificar um campo usando os valores de outros campos no documento.
Este pipeline:
combina as classificações do visualizador do IMDB e do Tomatoes em um novo campo de array
combinedRatingsdefine o campo
ratingsUpdatedremove os campos
imdb.ratingetomatoes.viewer.ratingoriginais de todos os documentos correspondentes
db.movies.updateMany( { year: { $gte: 2010, $lte: 2019 } }, [ { $set: { combinedRatings: [ "$imdb.rating", "$tomatoes.viewer.rating" ], ratingsUpdated: "$$NOW" } }, { $unset: [ "imdb.rating", "tomatoes.viewer.rating" ] } ] )
Observação
Nesse pipeline, $set e $unset são estágios de agregação, diferentes dos operadores de atualização. Os estágios de agregação $set e $unset adicionam novos campos aos documentos e não modificam os valores dos campos existentes.
Para obter mais informações sobre os operadores de atualização, consulte $set e $unset.
- Primeira etapa
O estágio
$set:cria um novo campo de array
combinedRatingscujos elementos são o conteúdo atual dosimdb.ratingtomatoes.viewer.ratingcampos edefine o campo
ratingsUpdatedpara o valor da variável de agregaçãoNOW.
- Segunda etapa
- O estágio
$unsetremove os camposimdb.ratingetomatoes.viewer.rating.
Após o comando, os filmes correspondentes dos 2010s têm uma array combinedRatings com valores de classificação e um carimbo de data/hora.
Exemplo 2: Atualização com Pipeline de Agregação Usando Campos Existentes Condicionalmente
Usando um pipeline de agregação , você pode atualizar filmes dos 2010s com uma pontuação de classificação combinada calculada (média das classificações dos visualizadores do IMDB e Tomatoes) e atribuir uma nota de letra com base nessa pontuação.
db.movies.updateMany( { year: { $gte: 2010, $lte: 2019 }, "imdb.rating": { $exists: true }, "tomatoes.viewer.rating": { $exists: true } }, [ { $set: { combinedScore: { $trunc: [ { $avg: [ "$imdb.rating", "$tomatoes.viewer.rating" ] }, 1 ] }, scoreUpdated: "$$NOW" } }, { $set: { ratingGrade: { $switch: { branches: [ { case: { $gte: [ "$combinedScore", 8 ] }, then: "A" }, { case: { $gte: [ "$combinedScore", 6 ] }, then: "B" }, { case: { $gte: [ "$combinedScore", 4 ] }, then: "C" }, { case: { $gte: [ "$combinedScore", 2 ] }, then: "D" } ], default: "F" } } } } ] )
Observação
Nesse pipeline, $set e $unset são estágios de agregação, diferentes dos operadores de atualização. Os estágios de agregação $set e $unset adicionam novos campos aos documentos e não modificam os valores dos campos existentes.
Para obter mais informações sobre os operadores de atualização, consulte $set e $unset.
- Primeira etapa
O estágio
$set:calcula um novo campo
combinedScorecom base na média dosimdb.ratingtomatoes.viewer.ratingcampos e. Consulte$avgpara obter mais informações sobre o operador$avgde agregação e para$truncobter mais informações sobre o$truncoperador de agregação truncada.define o campo
scoreUpdatedpara o valor da variável de agregaçãoNOW.
- Segunda etapa
- O estágio
$setcalcula um novo camporatingGradecom base no campocombinedScorecalculado no estágio anterior. Consulte$switchpara obter mais informações sobre o operador de aggregation do$switch.
Após o comando, os filmes correspondentes têm uma pontuação combinada e uma nota de letra.
Atualizar Vários Documentos com Inserção
A operação a seguir atualiza todos os filmes lançados após 2020 e dirigidos por Victor Nolan:
db.movies.updateMany( { year: { $gt: 2020 }, directors: "Christopher Nolan" }, { $set: { "upcomingRelease": true } }, { upsert: true } )
Neste exemplo, como nenhum documento corresponde ao filtro upsert e true é, updateMany() insere um novo documento com um gerado,_id bem como as condições de igualdade de filter e update modificadores.
Atualize com preocupação de gravação
Dado um conjunto de réplicas de três membros, a operação a seguir especifica um w de majority e wtimeout de 100
db.movies.updateMany( { title: "The Godfather" }, { $inc: { num_mflix_comments: 10 }, $set: { trending: true } }, { w: "majority", wtimeout: 100 } )
Se a confirmação demorar mais que o limite wtimeout, o MongoDB lançará uma exceção.
A tabela a seguir explica os possíveis valores de errInfo.writeConcern.provenance:
Proveniência | Descrição |
|---|---|
| A preocupação de gravação foi especificada no aplicativo. |
| A preocupação de gravação originou-se de um valor padrão personalizado definido. Consulte |
| A preocupação de gravação originada do campo |
| A preocupação de gravação originou-se do servidor na ausência de todas as outras especificações de preocupação de gravação. |
Especifique o agrupamento
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 operação a seguir usa um agrupamento que não diferencia maiúsculas de minúsculas para combinar filmes com o gênero "drum" com qualquer combinação de minúsculas e maiúsculas.
db.movies.updateMany( { genres: "drama" }, { $set: { genreNormalized: true } }, { collation: { locale: "en", strength: 1 } } )
Especificar arrayFilters para uma Operação de Atualização de array
Ao atualizar um campo de array, você pode especificar arrayFilters que determinam quais elementos de array atualizar.
Atualizar elementos que correspondem aos critérios arrayFilters
Adicione uma array ratings a alguns filmes combinando suas várias pontuações de classificação:
db.movies.updateMany( { "imdb.rating": { $exists: true }, "tomatoes.viewer.rating": { $exists: true }, "tomatoes.critic.rating": { $exists: true }, year: { $gte: 2010, $lte: 2015 } }, [ { $set: { ratings: [ { $multiply: ["$imdb.rating", 10] }, { $multiply: ["$tomatoes.viewer.rating", 10] }, { $multiply: ["$tomatoes.critic.rating", 10] } ] } } ] )
Para atualizar todas as classificações que são maiores ou iguais a 100 na ratings array, use o operador posicional filtrado com $[<identifier>] a arrayFilters opção:
db.movies.updateMany( { ratings: { $gte: 100 } }, { $set: { "ratings.$[element]" : 100 } }, { arrayFilters: [ { "element": { $gte: 100 } } ] } )
Após a operação, todos os valores de classificação maiores ou iguais a 100 nas arrays ratings são definidos como 100.
Atualizar elementos específicos de uma array de documentos
Adicione uma array ratingDetails a filmes com fontes de classificação individuais:
db.movies.updateMany( { "imdb.rating": { $exists: true }, "tomatoes.viewer.rating": { $exists: true }, year: { $gte: 2010, $lte: 2012 } }, [ { $set: { ratingDetails: [ { source: "imdb", score: "$imdb.rating", weight: 10 }, { source: "tomatoes_viewer", score: "$tomatoes.viewer.rating", weight: 8 }, { source: "tomatoes_critic", score: "$tomatoes.critic.rating", weight: 7 } ] } } ] )
Para modificar o valor do weight campo para 10 para todos os elementos da ratingDetails matriz onde a pontuação é maior ou igual 8 a, use o operador posicional filtrado $[<identifier>] arrayFilterscom:
db.movies.updateMany( { ratingDetails: { $exists: true } }, { $set: { "ratingDetails.$[elem].weight" : 10 } }, { arrayFilters: [ { "elem.score": { $gte: 8 } } ] } )
Após a operação, todas as fontes de classificação com pontuações menores ou iguais a 8 têm seu peso definido como 10.
Especifique hint para operações de atualização
Crie o seguinte índice na coleção:
db.movies.createIndex( { rated: 1 } )
A seguinte operação de atualização sugere explicitamente o uso do índice {
rated: 1 }:
Observação
Se você especificar um índice que não existe, a operação emitirá erros.
db.movies.updateMany( { "num_mflix_comments": { $lte: 5 }, "rated": "G" }, { $set: { "familyFriendly": true } }, { hint: { rated: 1 } } )
Para ver se o índice sugerido é usado, execute o pipeline $indexStats:
db.movies.aggregate( [ { $indexStats: { } }, { $sort: { name: 1 } }, { $match: {key: { rated: 1 } } } ] )
Erros de preocupação de gravação em clusters fragmentados
Alterado na versão 8.1.2.
Quando db.collection.updateMany() é executado em mongos em um cluster fragmentado, um writeConcernError é sempre relatado na resposta, mesmo quando ocorre um ou mais erros. Em versões anteriores, outros erros às vezes faziam com que db.collection.updateMany() não relatasse erros de preocupação de gravação.
Por exemplo, se um documento falhar na validação, desencadeando um erro DocumentValidationFailed e também ocorrer um erro de preocupação de gravação , o erro DocumentValidationFailed e o writeConcernError serão retornados no campo de nível superior da resposta.
Roles de usuário e atualizações de documentos
A partir do MongoDB 7.0, você pode usar a nova variável de sistemaUSER_ROLES para retornar funções de usuário .
O exemplo nesta seção mostra atualizações de campos em uma collection que contém informações médicas. O exemplo lê os roles atuais do usuário da variável de sistema USER_ROLES e só executa as atualizações se o usuário tiver um role específico.
Para usar uma variável do sistema, adicione $$ ao início do nome da variável. Especifique a variável de sistema USER_ROLES como $$USER_ROLES.
O exemplo cria estes usuários:
Jamescom um roleBilling.Michellecom um roleProvider.
Execute as seguintes etapas para criar os roles, os usuários e a collection:
Criar as funções
Crie roles denominados Billing e Provider com os recursos e privilégios exigidos.
Executar:
db.createRole( { role: "Billing", privileges: [ { resource: { db: "test", collection: "medicalView" }, actions: [ "find" ] } ], roles: [ ] } ) db.createRole( { role: "Provider", privileges: [ { resource: { db: "test", collection: "medicalView" }, actions: [ "find" ] } ], roles: [ ] } )
Faça login como Michelle, que tem o role Provider, e execute uma atualização:
O exemplo anterior usa $setIntersection para retornar documentos onde a interseção entre a string "Provider" e os roles de usuário do $$USER_ROLES.role não está vazia. Michelle tem o role Provider, então a atualização é executada.
Em seguida, faça login como James, que não tem o role Provider e tente realizar a mesma atualização:
Tentativa de realizar atualização
Executar:
// Attempt to update many documents db.medical.updateMany( // User must have the Provider role to perform the update { $expr: { $ne: [ { $setIntersection: [ [ "Provider" ], "$$USER_ROLES.role" ] }, [] ] } }, // Update diagnosisCode { $set: { diagnosisCode: "ACH 02"} } )
O exemplo anterior não atualiza nenhum documento.