Você não pode consultar os valores do documento que deseja atualizar, portanto, precisará de uma consulta para recuperar o documento e outra para atualizá-lo. Parece que há uma solicitação de recurso para isso em
OPEN
estado desde 2016. Se você tem uma coleção com documentos que se parecem com:
{ "_id" : ObjectId("590a4aa8ff1809c94801ecd0"), "name" : "bar" }
Usando o shell do MongoDB, você pode fazer algo assim:
db.test.find({ name: "bar" }).snapshot().forEach((doc) => {
doc.name = "foo-" + doc.name;
db.test.save(doc);
});
O documento será atualizado conforme o esperado:
{ "_id" : ObjectId("590a4aa8ff1809c94801ecd0"), "name": "foo-bar" }
Observe o
.snapshot()
call. Isso garante que a consulta não retornará um documento várias vezes porque uma operação de gravação intermediária o move devido ao aumento no tamanho do documento. Aplicando isso ao seu exemplo do Mongoose, conforme explicado em este exemplo oficial :
Cat.findById(1, (err, cat) => {
if (err) return handleError(err);
cat.name = cat.name + "bar";
cat.save((err, updatedCat) => {
if (err) return handleError(err);
...
});
});
Vale a pena mencionar que existe um
$concat
operador na estrutura de agregação, mas infelizmente você não pode usá-lo em uma update
consulta. De qualquer forma, dependendo do que você precisa fazer, você pode usar isso junto com o
$out
operador para salvar os resultados da agregação em uma nova coleção. Com esse mesmo exemplo, você fará:
db.test.aggregate([{
$match: { name: "bar" }
}, {
$project: { name: { $concat: ["foo", "-", "$name"] }}
}, {
$out: "prefixedTest"
}]);
E uma nova coleção
prefixedTest
será criado com documentos que se parecem com:{ "_id" : ObjectId("XXX"), "name": "foo-bar" }
Apenas como referência, há outra pergunta interessante sobre esse mesmo tópico com algumas respostas que vale a pena ler:Atualizar o campo MongoDB usando o valor de outro campo