No MongoDB o
db.collection.findOneAndReplace()
O método substitui um único documento com base no filtro especificado. 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.findOneAndReplace()
método para substituir um desses documentos. db.pets.findOneAndReplace(
{ "type": "Dog" },
{ "name": "Bruno", "type" : "Horse" }
)
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" : "Bruno", "type" : "Horse" } { "_id" : 2, "name" : "Bark", "type" : "Dog" } { "_id" : 3, "name" : "Meow", "type" : "Cat" }
Podemos ver que o primeiro documento foi substituído pelo novo documento.
Observe que o documento de substituição não pode especificar um
_id
valor que difere do _id
valor no documento substituído. Devolva o documento modificado
Por padrão, o documento original é retornado quando você usa
db.collection.findOneAndReplace()
. 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.findOneAndReplace(
{ "type": "Dog" },
{ "handle": "Harry", "DOB" : "2020-05-12", "points": 10 },
{ returnNewDocument: true }
)
Resultado:
{ "_id" : 2, "handle" : "Harry", "DOB" : "2020-05-12", "points" : 10 }
Desta vez o outro cão foi atualizado. Neste caso, fizemos uma alteração mais significativa, e podemos ver que o documento de retorno reflete isso.
Podemos verificar a coleção novamente para ver o documento substituído.
db.pets.find()
Resultado:
{ "_id" : 1, "name" : "Bruno", "type" : "Horse" } { "_id" : 2, "handle" : "Harry", "DOB" : "2020-05-12", "points" : 10 } { "_id" : 3, "name" : "Meow", "type" : "Cat" }
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.findOneAndReplace(
{ "_id": 4 },
{ "name": "Fluffy", "type": "Pooch", "DOB" : "2019-12-03", "points": 20 },
{
returnNewDocument: true
}
)
Resultado:
null
O documento não existia na coleção e, portanto,
findOneAndReplace()
retornou null
. Mesmo que não tenhamos especificado explicitamente 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, "name" : "Bruno", "type" : "Horse" } { "_id" : 2, "handle" : "Harry", "DOB" : "2020-05-12", "points" : 10 } { "_id" : 3, "name" : "Meow", "type" : "Cat" }
Exemplo usando upsert: true
Agora aqui está novamente, mas desta vez especificamos
upsert: true
. db.pets.findOneAndReplace(
{ "_id": 4 },
{ "name": "Fluffy", "type": "Pooch", "DOB" : "2019-12-03", "points": 20 },
{
upsert: true,
returnNewDocument: true
}
)
Resultado:
{ "_id" : 4, "name" : "Fluffy", "type" : "Pooch", "DOB" : "2019-12-03", "points" : 20 }
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" : "Bruno", "type" : "Horse" } { "_id" : 2, "handle" : "Harry", "DOB" : "2020-05-12", "points" : 10 } { "_id" : 3, "name" : "Meow", "type" : "Cat" } { "_id" : 4, "name" : "Fluffy", "type" : "Pooch", "DOB" : "2019-12-03", "points" : 20 }
Assim, podemos ver que o novo documento foi de fato alterado.
A sort
Parâmetro
Você pode usar o
sort
parâmetro para especificar uma ordem de classificação para os documentos correspondidos pelo filter
. Ao usar o
sort
parâmetro, um valor de 1
classifica os documentos em ordem crescente e um valor de -1
classifica-os em ordem decrescente. O argumento precisa ser fornecido como um documento. Por exemplo,
{ sort: { "salary": 1 } }
classifica pelo salary
campo em ordem crescente. Por exemplo, suponha que criamos uma coleção chamada
employees
com os seguintes documentos:db.employees.insertMany([
{ _id: 1, name: "Sandy", salary: 55000 },
{ _id: 2, name: "Sarah", salary: 128000 },
{ _id: 3, name: "Fritz", salary: 25000 },
{ _id: 4, name: "Chris", salary: 45000 },
{ _id: 5, name: "Beck", salary: 82000 }
])
Poderíamos executar o código a seguir para encontrar documentos com um salário inferior a 60.000 e, em seguida, substituir aquele que é o mais baixo desses documentos.
db.employees.findOneAndReplace(
{ "salary": { $lt: 60000 } },
{ "name": "Fluffy", "salary": 250000 },
{
sort: { "salary": 1 }
}
)
Resultado:
{ "_id" : 3, "name" : "Fritz", "salary" : 25000 }
Isso mostra o documento antes de ser atualizado. Como esperado, o funcionário com o menor salário foi substituído por um novo salário (e um novo nome).
Veja como estão os documentos agora.
db.employees.find()
Resultado:
{ "_id" : 1, "name" : "Sandy", "salary" : 55000 } { "_id" : 2, "name" : "Sarah", "salary" : 128000 } { "_id" : 3, "name" : "Fluffy", "salary" : 250000 } { "_id" : 4, "name" : "Chris", "salary" : 45000 } { "_id" : 5, "name" : "Beck", "salary" : 82000 }
Então podemos ver que Fritz foi substituído por Fluffy que tem um salário muito melhor.
Vamos reverter para o documento original.
db.employees.remove({})
db.employees.insertMany([
{ _id: 1, name: "Sandy", salary: 55000 },
{ _id: 2, name: "Sarah", salary: 128000 },
{ _id: 3, name: "Fritz", salary: 25000 },
{ _id: 4, name: "Chris", salary: 45000 },
{ _id: 5, name: "Beck", salary: 82000 }
])
Agora vamos executar o mesmo
findOneAndReplace()
código novamente, mas desta vez vamos classificá-lo em ordem decrescente. db.employees.findOneAndReplace(
{ "salary": { $lt: 60000 } },
{ "name": "Fluffy", "salary": 250000 },
{
sort: { "salary": -1 }
}
)
Resultado:
{ "_id" : 1, "name" : "Sandy", "salary" : 55000 }
Desta vez, Sandy foi substituído.
Vamos verificar a coleção novamente.
db.employees.find()
Resultado:
{ "_id" : 1, "name" : "Fluffy", "salary" : 250000 } { "_id" : 2, "name" : "Sarah", "salary" : 128000 } { "_id" : 3, "name" : "Fritz", "salary" : 25000 } { "_id" : 4, "name" : "Chris", "salary" : 45000 } { "_id" : 5, "name" : "Beck", "salary" : 82000 }
Como esperado.
Mais informações
O
db.collection.findOneAndReplace()
O método também aceita outros parâmetros, como projection
(para especificar um subconjunto de campos a serem retornados), maxTimeMS
, e collation
. Consulte a documentação do MongoDB para
db.collections.findOneAndReplace()
Para maiores informações.