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

db.collection.findOneAndUpdate()

Nesta página

  • Definição
  • Compatibilidade
  • Sintaxe
  • Comportamento
  • Exemplos
db.collection.findOneAndUpdate( filter, update, options )

Importante

Método mongosh

Esta página documenta um método mongosh . Esta não é a documentação para comandos de banco de dados ou drivers específicos de idioma, como Node.js.

Para o comando do banco de dados, consulte o comando update.

Para drivers de API do MongoDB, consulte a documentação do driver MongoDB específica do idioma.

Para a documentação de shell legada do mongo, consulte a documentação para a versão correspondente do MongoDB Server:

mongo shell v4.4

Atualiza um único documento com base nos critérios filter e sort.

Retorna:Retorna o documento original por padrão. Retorna o documento atualizado se returnNewDocument estiver definido como true ou returnDocument estiver definido como after.

Você pode utilizar o db.collection.findOneAndUpdate() para implantações hospedadas nos seguintes ambientes:

  • MongoDB Atlas: o serviço totalmente gerenciado para implantações 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 findOneAndUpdate() tem o seguinte formulário:

db.collection.findOneAndUpdate(
<filter>,
<update document or aggregation pipeline>,
{
writeConcern: <document>,
projection: <document>,
sort: <document>,
maxTimeMS: <number>,
upsert: <boolean>,
returnDocument: <string>,
returnNewDocument: <boolean>,
collation: <document>,
arrayFilters: [ <filterdocument1>, ... ]
}
)

O método findOneAndUpdate() utiliza os seguintes parâmetros:

Parâmetro
Tipo
Descrição
filter
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.

Para atualizar o primeiro documento retornado na collection, especifique um documento vazio { }.

Se não for especificado, o padrão será um documento vazio.

Se o campo de query não for um documento, a operação retornará um erro.

Se nenhum documento corresponder ao filter, nenhum documento será atualizado.

update
documento ou array

O documento de atualização ou um pipeline de agregação.

  • Se for passado um documento com expressões de operador de atualização, db.collection.findOneAndUpdate() executará a modificação especificada.

    Observação

    O documento deve conter somente operadores de atualização. Você não pode especificar um documento substituto { <field1>: <value1>, ...}. Para usar um documento de substituição, consulte db.collection.findOneAndReplace().

  • Se for passado um aggregation pipeline [ <stage1>, <stage2>, ... ], db.collection.findOneAndUpdate() modificará o documento de acordo com o pipeline. O pipeline pode consistir nas seguintes etapas:

writeConcern
documento

Opcional. Um documento que expressa o write concern. Omitir para usar o write concern padrão.

{ w: <value>, j: <boolean>, wtimeout: <number> }

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.

projection
documento

Opcional. Um subconjunto de campos para retornar.

Para retornar todos os campos no documento retornado, omita este parâmetro.

Se o argumento de projeção não for um documento, a operação apresentará erro.

sort
documento

Opcional. Especifica uma ordem de classificação para os documentos correspondidos pelo filter.

Se o argumento de classificação não for um documento, a operação apresentará erro.

Consulte cursor.sort().

maxTimeMS
número
Opcional. Especifica um limite de tempo em milissegundos dentro do qual a operação deve ser concluída. Lança um erro se o limite for excedido.
upsert
booleano

Opcional. Quando true, findOneAndUpdate() ou:

  • Cria um novo documento se nenhum documento corresponder a filter. Para obter mais detalhes, consulte comportamento upsert. Retorna null após inserir o novo documento, a menos que returnNewDocument seja true.

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

returnDocument
string

Opcional. A partir de mongosh 0.13.2, returnDocument é uma alternativa para returnNewDocument. Se ambas as opções forem configuradas, o returnDocument terá precedência.

returnDocument: "before" retorna o documento original. returnDocument: "after" retorna o documento atualizado.

returnNewDocument
booleano

Opcional. Quando true, retorna o documento atualizado em vez do documento original.

Padrão é false.

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.

arrayFilters
array

Opcional. Um array de documentos de filtro que determina quais elementos do array modificar para uma operação de atualização em um campo do 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.

Observaçã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 } }
]

Por exemplo, consulte Operações de atualização de array com arrayFilters.

Observação

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

db.collection.findOneAndUpdate() atualiza o primeiro documento correspondente na collection que corresponde a filter. Se nenhum documento corresponder a filter, nenhum documento será atualizado.

O parâmetro sort pode ser usado para influenciar qual documento é atualizado.

Importante

Consistência de linguagem

Como parte de tornar a projeção find() e findAndModify() consistente com o estágio $project da agregação,

O parâmetro projection obtém um documento no seguinte formato:

{ field1 : <value>, field2 : <value> ... }
Projeção
Descrição
<field>: <1 or true>
Especifica a inclusão de um campo. Se você especificar um número inteiro diferente de zero para o valor de projeção, a operação tratará o valor como true.
<field>: <0 or false>
Especifica a exclusão de um campo.
"<field>.$": <1 or true>

Usa o operador de projeção de array $ para retornar o primeiro elemento que corresponde à condição de consulta no campo de array. Se você especificar um número inteiro diferente de zero para o valor de projeção, a operação tratará o valor como true.

Não disponível para visualizações.

<field>: <array projection>

Usa os operadores de projeção de array ($elemMatch, $slice) para especificar os elementos da array a serem incluídos.

Não disponível para visualizações.

<field>: <aggregation expression>

Especifica o valor do campo projetado.

Com o uso de expressões de agregação e sintaxe, incluindo o uso de literais e variáveis de agregação, você pode projetar novos campos ou projetar campos existentes com novos valores.

  • Se você especificar um literal não numérico e não booleano (como uma string literal ou um array ou uma expressão de operador) para o valor de projeção, o campo será projetado com o novo valor, por exemplo:

    • { field: [ 1, 2, 3, "$someExistingField" ] }

    • { field: "New String Value" }

    • { field: { status: "Active", total: { $sum: "$existingArray" } } }

  • Para projetar um valor literal para um campo, use a expressão de aggregation $literal, por exemplo:

    • { field: { $literal: 5 } }

    • { field: { $literal: true } }

    • { field: { $literal: { fieldWithValue0: 0, fieldWithValue1: 1 } } }

Para campos em documentos incorporados, você pode especificar o campo usando:

  • notação de pontos, por exemplo "field.nestedfield": <value>

  • formulário aninhado, por exemplo { field: { nestedfield: <value> } }

O campo _id é incluído nos documentos retornados por padrão, a menos que você especifique explicitamente _id: 0 na projeção para suprimir o campo.

Uma projection não pode conter especificações de inclusão e exclusão, com exceção do campo _id:

  • Em projeções que incluem explicitamente campos, o campo _id é o único campo que você pode excluir explicitamente.

  • Em projeções que excluem explicitamente campos, o campo _id é o único campo que você pode incluir explicitamente; entretanto, o campo _id é incluído por padrão.

Para obter mais informações sobre "projection", consulte também:

Para usar db.collection.findOneAndUpdate() em uma collection fragmentada, o filtro de query deve incluir uma condição de igualdade na chave de shard.

documento em uma collection fragmentada podem não ter os campo principais do fragmento. Para direcionar um documento que não tenha a chave de shard, 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 do shard de um documento, a menos que o campo chave do shard seja o campo _id imutável.

Aviso

Documento em collection fragmentadas podem não ter os campo da chave de fragmento. Tenha cuidado para não remover acidentalmente a chave de fragmento ao alterar o valor da chave de fragmento de um documento.

Para modificar o valor chave do fragmento existente com db.collection.findOneAndUpdate():

  • 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 shard completa.

Os documentos em uma collection fragmentada podem não ter os campos de chave de shard. Para usar db.collection.findOneAndUpdate() para definir a chave de shard ausente do documento,

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

  • Você deve executar em uma transação ou como retryable write se o novo valor da chave de shard não for null.

  • Você deve incluir um filtro de igualdade na chave de shard 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.

Veja também:

db.collection.findOneAndUpdate() 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.findOneAndUpdate() com upsert: true pode ser executado em uma coleção existente ou uma coleção não existente. 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.findOneAndUpdate() atualizar um documento com êxito, a operação adicionará uma entrada no oplog (registro de operações). Se a operação falhar ou não localizar um documento para atualizar, a operação não adicionará uma entrada no oplog.

A collection grades contém documentos semelhantes aos seguintes:

{ _id: 6305, name : "A. MacDyver", "assignment" : 5, "points" : 24 },
{ _id: 6308, name : "B. Batlock", "assignment" : 3, "points" : 22 },
{ _id: 6312, name : "M. Tagnum", "assignment" : 5, "points" : 30 },
{ _id: 6319, name : "R. Stiles", "assignment" : 2, "points" : 12 },
{ _id: 6322, name : "A. MacDyver", "assignment" : 2, "points" : 14 },
{ _id: 6234, name : "R. Stiles", "assignment" : 1, "points" : 10 }

A operação a seguir encontra o primeiro documento onde name : R. Stiles e aumenta a pontuação em 5:

db.grades.findOneAndUpdate(
{ "name" : "R. Stiles" },
{ $inc: { "points" : 5 } }
)

A operação retorna o documento original antes da atualização:

{ _id: 6319, name: "R. Stiles", "assignment" : 2, "points" : 12 }

Se returnNewDocument fosse verdadeiro, a operação retornaria o documento atualizado.

A collection grades contém documentos semelhantes aos seguintes:

{ _id: 6305, name : "A. MacDyver", "assignment" : 5, "points" : 24 },
{ _id: 6308, name : "B. Batlock", "assignment" : 3, "points" : 22 },
{ _id: 6312, name : "M. Tagnum", "assignment" : 5, "points" : 30 },
{ _id: 6319, name : "R. Stiles", "assignment" : 2, "points" : 12 },
{ _id: 6322, name : "A. MacDyver", "assignment" : 2, "points" : 14 },
{ _id: 6234, name : "R. Stiles", "assignment" : 1, "points" : 10 }

A operação seguinte atualiza um documento onde name : "A. MacDyver". A operação classifica os documentos correspondentes por points crescente para atualizar o documento correspondente com o mínimo de pontos.

db.grades.findOneAndUpdate(
{ "name" : "A. MacDyver" },
{ $inc : { "points" : 5 } },
{ sort : { "points" : 1 } }
)

A operação retorna o documento original antes da atualização:

{ _id: 6322, name: "A. MacDyver", "assignment" : 2, "points" : 14 }

A seguinte operação usa projeção para retornar somente os campos _id, points e assignment no documento retornado:

db.grades.findOneAndUpdate(
{ "name" : "A. MacDyver" },
{ $inc : { "points" : 5 } },
{ sort : { "points" : 1 }, projection: { "assignment" : 1, "points" : 1 } }
)

A operação retorna o documento original somente com os campos especificados no documento projection e o campo _id como ele não foi explicitamente suprimido (_id: 0) no documento de projeção.

{ "_id" : 6322, "assignment" : 2, "points" : 14 }

A seguinte operação define um limite de tempo de 5ms para concluir a atualização:

try {
db.grades.findOneAndUpdate(
{ "name" : "A. MacDyver" },
{ $inc : { "points" : 5 } },
{ sort: { "points" : 1 }, maxTimeMS : 5 };
);
}
catch(e){
print(e);
}

Se a operação exceder o limite de tempo, ela retornará:

Error: findAndModifyFailed failed: { "ok" : 0, "errmsg" : "operation exceeded time limit", "code" : 50 }

A seguinte operação utiliza o campo upsert para inserir o documento de atualização se nenhum corresponder ao filter:

try {
db.grades.findOneAndUpdate(
{ "name" : "A.B. Abracus" },
{ $set: { "name" : "A.B. Abracus", "assignment" : 5}, $inc : { "points" : 5 } },
{ sort: { "points" : 1 }, upsert:true, returnNewDocument : true }
);
}
catch (e){
print(e);
}

A operação retorna o seguinte:

{
"_id" : ObjectId("5789249f1c49e39a8adc479a"),
"name" : "A.B. Abracus",
"assignment" : 5,
"points" : 5
}

Se returnNewDocument fosse falso, a operação retornará null, pois não há nenhum documento original para retornar.

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

A operação retorna o seguinte documento:

{ "_id" : 1, "category" : "café", "status" : "A" }

Observação

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

A partir do MongoDB 3.6, ao atualizar um campo de array, você pode especificar arrayFilters que determina quais elementos do array devem ser atualizados.

Observação

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

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 matriz grades , use o operador posicional filtrado $[<identifier>] com a opção arrayFilters no método db.collection.findOneAndUpdate() :

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

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

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

Observação

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

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

A operação a seguir localiza um documento em que o campo _id é igual a 1 e usa o operador posicional filtrado $[<identifier>] com arrayFilters para modificar o mean para todos os elementos na array grades em que a nota é maior ou igual a 85.

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

A operação atualiza o campo grades para um único documento e, após a operação, a collection tem 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 }
]
}

db.collection.findOneAndUpdate() pode aceitar 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).

Por exemplo, criar 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 }
]
}
] )

A operação a seguir localiza um documento em que o campo _id é igual a 1 e usa um aggregation pipeline para calcular um novo total de campo a partir do campo grades:

db.students2.findOneAndUpdate(
{ _id : 1 },
[ { $set: { "total" : { $sum: "$grades.grade" } } } ], // The $set stage is an alias for ``$addFields`` stage
{ returnNewDocument: true }
)

Observação

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

A operação retorna o documento atualizado:

{
"_id" : 1,
"grades" : [ { "grade" : 80, "mean" : 75, "std" : 6 }, { "grade" : 85, "mean" : 90, "std" : 4 }, { "grade" : 85, "mean" :85, "std" : 6 } ],
"total" : 250
}
← db.collection.findOneAndReplace()