No MongoDB o
db.collection.findOneAndUpdate()
O método atualiza um único documento com base no filter
e sort
critério. A
collection
parte é o nome da coleção com a qual executar a operação. Exemplo
Suponha que tenhamos uma coleção chamada
pets
que contém os seguintes documentos:{ "_id" : 1, "name" : "Wag", "type" : "Dog" } { "_id" : 2, "name" : "Bark", "type" : "Dog" } { "_id" : 3, "name" : "Meow", "type" : "Cat" }
Podemos usar o
db.collection.findOneAndUpdate()
método para atualizar um desses documentos. db.pets.findOneAndUpdate(
{ "type": "Dog" },
{ $set: { "type": "Cow" } }
)
Resultado:
{ "_id" : 1, "name" : "Wag", "type" : "Dog" }
Por padrão, ele retorna o documento original (não a versão modificada).
Observe que apenas um cão foi atualizado, embora existam dois cães na coleção.
Vamos conferir a coleção.
db.pets.find()
Resultado:
{ "_id" : 1, "name" : "Wag", "type" : "Cow" } { "_id" : 2, "name" : "Bark", "type" : "Dog" } { "_id" : 3, "name" : "Meow", "type" : "Cat" }
Podemos ver que o primeiro documento agora contém uma vaca em vez de um cachorro.
Devolva o documento modificado
Por padrão, o documento original é retornado quando você usa
db.collection.findOneAndUpdate()
. Se preferir que o documento modificado seja devolvido, use o
returnNewDocument
parâmetro. Vamos fazer outra modificação, mas desta vez usaremos
returnNewDocument: true
. db.pets.findOneAndUpdate(
{ "type": "Dog" },
{ $set: { "type": "Horse" } },
{ returnNewDocument: true }
)
Resultado:
{ "_id" : 2, "name" : "Bark", "type" : "Horse" }
Desta vez o outro cão foi atualizado. Neste caso, alteramos para um cavalo, e podemos ver que o documento de retorno reflete isso.
Upserts
Um upsert é uma opção que você pode usar em operações de atualização. Se o documento especificado não existir, um novo será inserido. Se sim existir, o documento original será atualizado (e nenhum documento será inserido).
Você pode realizar upserts especificando
upsert: true
. Exemplo usando upsert: false
Primeiro, aqui está um exemplo de tentativa de atualizar um documento inexistente quando
upsert: false
. db.pets.findOneAndUpdate(
{ "_id": 4 },
{ $set: { "name": "Barry", "type": "Badger" } },
{
returnNewDocument: true
}
)
Resultado:
null
O documento não existia na coleção e então
findOneAndUpdate()
retornou null
. Embora não tenhamos especificado upsert: false
, sabemos que era falso porque esse é o valor padrão (ou seja, esse é o valor usado quando você não especifica uma opção de upsert). Se dermos outra olhada na coleção, podemos ver que o documento não foi upserted.
db.pets.find()
Resultado:
{ "_id" : 1, "type" : "Cow" } { "_id" : 2, "name" : "Bark", "type" : "Horse" } { "_id" : 3, "name" : "Scratch", "type" : "Cat" }
Exemplo usando upsert: true
Agora aqui está novamente, mas desta vez especificamos
upsert: true
. db.pets.findOneAndUpdate(
{ "_id": 4 },
{ $set: { "name": "Barry", "type": "Badger" } },
{
upsert: true,
returnNewDocument: true
}
)
Resultado:
{ "_id" : 4, "name" : "Barry", "type" : "Badger" }
Desta vez, um novo documento é upserted e vemos o documento upserted como a saída (porque especificamos
returnNewDocument: true
). Vamos verificar a coleção novamente.
db.pets.find()
Resultado:
{ "_id" : 1, "name" : "Wag", "type" : "Cow" } { "_id" : 2, "name" : "Bark", "type" : "Horse" } { "_id" : 3, "name" : "Meow", "type" : "Cat" } { "_id" : 4, "name" : "Barry", "type" : "Badger" }
Assim, podemos ver que o novo documento foi de fato alterado.
Os arrayFilters
Parâmetro
Ao trabalhar com arrays, você pode usar os
arrayFilters
parâmetro junto com o posicional $
operador para determinar quais elementos da matriz devem ser atualizados. Isso permite que você atualize um elemento da matriz com base em seu valor, mesmo que você não saiba sua posição. Por exemplo, suponha que temos uma coleção chamada
players
com os seguintes documentos:{ "_id" : 1, "scores" : [ 1, 5, 3 ] } { "_id" : 2, "scores" : [ 8, 17, 18 ] } { "_id" : 3, "scores" : [ 15, 11, 8 ] }
Poderíamos executar a seguinte consulta para atualizar apenas os elementos do array que possuem um valor maior que um determinado valor (neste caso 10).
db.players.findOneAndUpdate(
{ scores: { $gte: 10 } },
{ $set: { "scores.$[e]" : 10 } },
{
arrayFilters: [ { "e": { $gte: 10 } } ]
}
)
Resultado:
{ "_id" : 2, "scores" : [ 8, 17, 18 ] }
Isso mostra o documento antes de ser atualizado. Como esperado, isso atualiza apenas um documento, mesmo que dois documentos correspondam aos critérios.
Veja como estão os documentos agora.
db.players.find()
Resultado:
{ "_id" : 1, "scores" : [ 1, 5, 3 ] } { "_id" : 2, "scores" : [ 8, 10, 10 ] } { "_id" : 3, "scores" : [ 15, 11, 8 ] }
O Documento 2 teve dois elementos do array atualizados, porque esses elementos correspondiam aos critérios.
Mais informações
O
db.collection.findOneAndUpdate()
O método também aceita outros parâmetros, como projection
(para especificar um subconjunto de campos a serem retornados), sort
, maxTimeMS
, e collation
. Consulte a documentação do MongoDB para
db.collections.findOneAndUpdate()
Para maiores informações.