Documentação
Introdução
products.updateOne({ _id: 'tea' }, { $set: { price: 9 }, $inc: { sold: 1 } });
products.updateMany({ stock: 0 }, { $set: { available: false } });
products.replaceOne({ _id: 'tea' }, { name: 'Green tea', price: 10 });
products.deleteOne({ _id: 'juice' });
products.deleteMany({ available: false });
products.bulkWrite([ /* várias das operações acima em uma única chamada */ ]);
Os filtros são consultas. Filtros por _id usam o índice, então { _id: x } é o jeito
mais rápido de chegar a um documento.
updateOne e updateMany
collection.updateOne(filter, update, { upsert }) // o primeiro que corresponder
collection.updateMany(filter, update, { upsert }) // todos que corresponderem
// → { matchedCount, modifiedCount, upsertedId }
modifiedCount conta os documentos que realmente mudaram: definir um campo com o valor que ele já
tem conta como correspondência, mas não como modificação (e não emite evento).
Operadores de atualização
| Operador | Efeito | Exemplo |
|---|---|---|
$set |
Define campos, criando os objetos que faltarem ao longo de caminhos "a.b" |
{ $set: { price: 9, 'supplier.city': 'Franca' } } |
$unset |
Remove campos (o valor é ignorado) | { $unset: { discount: '' } } |
$inc |
Soma um número; um campo ausente começa em 0 | { $inc: { stock: -1, sold: 1 } } |
$push |
Adiciona ao final de um array (criado se não existir); $each adiciona vários |
{ $push: { tags: 'new' } }, { $push: { tags: { $each: ['a', 'b'] } } } |
$pull |
Remove itens do array iguais a um valor, que atendam a uma condição ou que correspondam a um subdocumento | { $pull: { tags: 'old' } }, { $pull: { scores: { $lt: 5 } } }, { $pull: { items: { ok: false } } } |
Você pode combinar vários operadores em uma mesma atualização. Uma atualização deve conter apenas
operadores; um objeto simples ({ price: 9 }) lança um erro e indica o replaceOne.
Atualizações seguras
- Atômicas por chamada. Cada nova versão é calculada e validada antes de qualquer documento ser
substituído: se o
$incencontrar um campo de texto no 500º documento de umupdateMany, nada muda. - O
_idnão pode mudar (The _id field cannot be updated). - Schema verificado. Com um schema, a nova versão precisa satisfazê-lo (
ValidationError). - Erros claros.
Cannot $inc "name": it is not a number,Cannot $push to "tags": it is not an array,Unknown update operator $rename.
Upsert
users.updateOne(
{ email: 'ana@example.com' },
{ $set: { name: 'Ana' }, $inc: { visits: 1 } },
{ upsert: true }
);
// nada correspondeu: insere { email: 'ana@example.com', name: 'Ana', visits: 1 }
// → { matchedCount: 0, modifiedCount: 0, upsertedId: '…' }
O novo documento parte das condições de igualdade do filtro (field: value e
field: { $eq: value } no nível mais externo) e, em seguida, a atualização é aplicada. Os valores
padrão do schema são preenchidos.
replaceOne
products.replaceOne({ _id: 'tea' }, { name: 'Green tea', price: 10 });
products.replaceOne({ name: 'Mate' }, { name: 'Mate', price: 7 }, { upsert: true });
Substitui o documento inteiro do primeiro que corresponder e mantém o seu _id (um _id diferente
no documento substituto lança um erro). O documento substituto não pode conter operadores de
atualização.
deleteOne e deleteMany
products.deleteOne({ _id: 'tea' }); // { deletedCount: 1 }
products.deleteMany({ price: { $gt: 100 } });
products.deleteMany({}); // esvazia a coleção
Um filtro é sempre obrigatório: deleteMany() sem filtro lança um erro
(The filter must be a query object, use {} to match every document), então esvaziar uma coleção é
sempre um {} intencional.
bulkWrite
Várias escritas em uma única chamada, com as operações do MongoDB:
const result = products.bulkWrite([
{ insertOne: { document: { _id: 'mate', name: 'Mate', price: 7 } } },
{ updateOne: { filter: { _id: 'tea' }, update: { $inc: { stock: 10 } } } },
{ updateMany: { filter: { stock: 0 }, update: { $set: { available: false } } } },
{ replaceOne: { filter: { _id: 'juice' }, replacement: { name: 'Orange juice', price: 11 }, upsert: true } },
{ deleteOne: { filter: { _id: 'old' } } },
{ deleteMany: { filter: { discontinued: true } } }
]);
// { insertedCount, matchedCount, modifiedCount, deletedCount, upsertedCount, insertedIds: { 0: 'mate' }, upsertedIds: {} }
- As operações rodam em ordem. Filtros por
_idusam o índice: 50 000updateOnepor_idlevam uma fração de segundo. - Um evento por tipo, no final: um evento
updatelistando todos os documentos atualizados, uminsert… em vez de um por operação. Consultas vivas e ouvintes são atualizados uma única vez. - Erros, como no MongoDB. Com
ordered: true(o padrão), a primeira operação que falhar interrompe o lote; com{ ordered: false }, as demais continuam rodando. Em ambos os casos, as operações anteriores ao erro permanecem aplicadas, e umBulkWriteErrorinforma o que aconteceu:
try {
products.bulkWrite(operations, { ordered: false });
} catch (error) {
error.name; // 'BulkWriteError'
error.writeErrors; // [{ index: 3, operation: {…}, error: ValidationError }]
error.result; // as contagens do que foi aplicado
}
Use bulkWrite para aplicar mudanças vindas de um servidor, para importar dados que misturam linhas
novas e existentes, ou para atualizar muitos documentos por id com valores diferentes.
Eventos
Toda escrita que muda alguma coisa emite um evento (insert, update, replace, delete, e
change para todos eles); veja Eventos. Escritas que não mudam nada não emitem nada.