Bulk operations con bulkWrite en MongoDB | Nicolás Garzón
Inicio Wiki MongoDB Bulk operations Volver a MongoDBMongoDB
Bulk operations Agrupa inserciones, actualizaciones, reemplazos y eliminaciones con bulkWrite, controlando orden, errores parciales, lotes y rendimiento.
Última actualización Actualizada 25 de jul de 2026
Las bulk operations agrupan múltiples inserts, updates, replacements y deletes en una sola llamada lógica para reducir viajes de red y procesar lotes con mayor eficiencia. .
Nota anteriorEliminaciones Nota siguiente Cursors No convierten automáticamente el lote completo en una transacción
JavaScript
Copiar db. products. bulkWrite ( [
{
updateOne : {
filter : { businessId, sku : 'CAF-001' } ,
update : {
$set : { name : 'Café molido' , updatedAt : new Date ( ) } ,
$setOnInsert : { createdAt : new Date ( ) }
} ,
upsert : true
}
} ,
{
deleteOne : {
filter : { businessId, sku : 'OLD-001' }
}
}
] , {
ordered : false
} ) ; Enviar diez mil operaciones una por una implica:
diez mil round trips lógicos;
más latencia;
overhead de protocolo;
manejo de errores fragmentado;
presión innecesaria sobre el pool.
bulkWrite permite agrupar trabajo, manteniendo una descripción por operación y un resultado agregado.
insertOne;
updateOne;
updateMany;
replaceOne;
deleteOne;
deleteMany.
Cada entrada conserva su filtro, update y opciones. El bulk no obliga a que todas operen sobre el mismo tipo de cambio, aunque sí pertenecen a la misma colección en la API tradicional de colección.
Con ordered: true, MongoDB procesa respetando el orden lógico y detiene operaciones posteriores cuando ocurre un error que interrumpe el lote.
Texto
Copiar op 1 → éxito
op 2 → éxito
op 3 → duplicate key
op 4 → no se intentaLas operaciones exitosas anteriores no se revierten.
cada operación depende de la anterior;
el orden tiene significado;
continuar después del error sería incorrecto.
Pero si existe dependencia real que exige all-or-nothing, un ordered bulk sigue sin ser una transacción.
Con ordered: false, el servidor puede continuar con operaciones independientes aunque alguna falle.
Texto
Copiar op 1 → éxito
op 2 → duplicate key
op 3 → éxito
op 4 → validation error
op 5 → éxitoEs útil para imports y sincronizaciones donde cada documento puede evaluarse por separado.
No debes depender del orden exacto de ejecución ni asumir que todos los errores llegan en el mismo orden del input.
El resultado puede contener conteos de:
inserts;
matches;
modifications;
deletes;
upserts;
IDs insertados o upsertados.
Cuando existe error, el driver puede lanzar una excepción que contiene información parcial. La aplicación debe conservar:
índice de la operación original;
identidad lógica;
error concreto;
estado aplicado;
posibilidad de retry.
No registres documentos sensibles completos para depurar.
Texto
Copiar insert order
update stock
insert auditUn bulk no garantiza que las tres operaciones se apliquen juntas, especialmente si pertenecen a colecciones diferentes. Para una invariantes multi-documento puede utilizarse una transacción, rediseñar el aggregate o implementar un workflow compensatorio.
No envíes millones de operaciones en un único objeto. Divide en batches según:
memoria de la aplicación;
tamaño BSON del comando;
latencia;
replication lag;
capacidad de reanudar;
tiempo de ejecución;
observabilidad.
TypeScript
Copiar const batchSize = 500 ;
for ( const batch of chunk ( items, batchSize) ) {
await collection. bulkWrite (
batch. map ( item => buildOperation ( item) ) ,
{ ordered: false }
) ;
await saveCheckpoint ( batch. at ( - 1 ) ! . sourceId) ;
} El tamaño óptimo se mide. Documentos grandes pueden requerir batches menores.
Un import puede reiniciarse después de aplicar parte del lote. Las operaciones deben converger:
JavaScript
Copiar {
updateOne : {
filter : { businessId, externalId } ,
update : { $set : normalizedFields } ,
upsert : true
}
} JavaScript
Copiar db. products. createIndex (
{ businessId : 1 , externalId : 1 } ,
{ unique : true }
) ; JavaScript
Copiar { $inc : { stock : 10 } } duplica el efecto. Necesita operation ID, versionado o una estrategia de reconciliación.
valida archivo y encoding;
normaliza tipos;
detecta duplicados dentro del input;
valida tenant y permisos;
crea operaciones idempotentes;
procesa batches;
registra checkpoints;
maneja errores por fila;
compara conteos;
genera reporte de reconciliación.
El éxito del comando no demuestra que el resultado sea semánticamente correcto.
JavaScript
Copiar {
updateOne : {
filter : {
_id,
schemaVersion : 1
} ,
update : {
$set : {
newField : value,
schemaVersion : 2
}
}
}
} La precondition evita volver a migrar documentos ya actualizados. Procesar por _id permite reanudar.
Se puede ejecutar bulk dentro de una transacción compatible, pero entonces aplican:
límites y duración de transacción;
recursos retenidos;
retry de commit;
tamaño del workload;
impacto en sharding;
necesidad real de atomicidad.
No introduzcas una transacción para un import enorme; suele ser mejor batches idempotentes.
El bulk utiliza write concern. Un concern fuerte aumenta la garantía y puede aumentar latencia. Un timeout de write concern no significa automáticamente que ninguna operación se aplicó.
La reconciliación necesita identidades y queries verificables.
Consume memoria y es difícil de reanudar.
Los éxitos anteriores permanecen.
Duplica efectos no idempotentes.
Los upserts concurrentes pueden competir.
Operaciones posteriores pueden ejecutar aunque una precondición lógica falló.
El usuario no sabe qué registro corregir.
Genera scans repetidos y presión operacional.
Algunos documentos ya existen o compiten concurrentemente.
Schema validation rechaza solo esa operación en unordered.
El driver puede reportar error transitorio o resultado ambiguo.
El comportamiento depende del orden y updates; deduplica antes.
Las operaciones pueden distribuirse entre shards. La shard key en filtros mejora targeting.
El checkpoint debe guardarse después de confirmar el batch, no antes.
Conserva índice de operación.
Revisa error codes.
Separa duplicate, validation, network y write concern.
Comprueba resultados parciales.
Consulta identidades aplicadas.
Revisa tamaño de batches.
Observa replication lag y CPU.
Analiza filtros e índices.
Reanuda desde checkpoint.
Ejecuta reconciliación final.
Bulk operations optimizan transporte y administración de lotes. Ordered controla continuidad, unordered favorece operaciones independientes. Ninguno ofrece all-or-nothing por defecto. La confiabilidad proviene de batches controlados, idempotencia, índices, checkpoints y reconciliación.
Comprueba lo aprendido
¿Qué diferencia existe entre ordered y unordered?
¿Por qué un bulk no es una transacción?
¿Cómo reanudarías un import después de un fallo?
¿Qué operaciones no son idempotentes al repetirse?
¿Qué información debes conservar para errores parciales?
¿Cuándo reducirías el tamaño del batch?