Cuando trabajas con sensores IoT que envían lecturas constantes a MongoDB, necesitas decidir entre insertar un documento nuevo o actualizar uno existente. La operación upsert en MongoDB resuelve ese dilema con una sola instrucción y evita consultas extra para verificar si el documento ya existe.
Esto te interesa si construyes pipelines de datos para sensores, registros diarios o cualquier sistema donde la lógica dependa de "si existe, actualiza; si no, crea".
Por qué guardar lecturas de sensores en MongoDB
Las bases de datos documentales como MongoDB encajan muy bien con cargas IoT porque escriben mucho y permiten estructuras flexibles por documento.
En el caso de la clase, la colección iot dentro de Platzi Store guarda un documento por sensor y por fecha. Cada documento contiene:
- Un identificador del sensor, por ejemplo
A0001.
- Una fecha, por ejemplo el 1 de enero de 2022.
- Un array
readings con todas las lecturas de ese sensor en ese día.
La regla de modelado es clara: un sensor + una fecha = un solo documento. La primera lectura del día crea el documento. Las siguientes lecturas solo agregan valores al array.
¿Por qué usar bases de datos documentales para IoT? Porque los sensores escriben con mucha frecuencia y los documentos permiten guardar arrays de lecturas crecientes sin reestructurar tablas. [01:08]
Cómo decidir entre insertOne y updateOne sin upsert
Antes de conocer upsert, la solución típica era programática. Lanzas un find con la consulta del sensor y la fecha, aplicas un count y según el resultado eliges el método.
- Si el count es cero, ejecutas
insertOne con el documento completo.
- Si el count es mayor a cero, ejecutas
updateOne y haces push de la nueva lectura.
Funciona, pero te obliga a viajar dos veces a la base de datos y a escribir lógica condicional en tu aplicación. Aquí entra la solución elegante de Mongo.
Cómo agregar una lectura con push y corregir errores con pop
Durante la clase aparece un detalle muy común. Al ejecutar un updateOne con $push sobre readings, se insertó un sub-array en lugar de un valor numérico suelto. El error estaba en pasar un array al operador push cuando solo debías pasar el valor directo. [05:30]
Para revertirlo se usa $pop, un operador que elimina elementos de un array según su posición:
$pop: 1 elimina el último elemento del array.
$pop: -1 elimina el primer elemento del array.
Después de limpiar el array con pop, se vuelve a hacer push pasando el valor numérico tal cual y el documento queda correcto.
Cómo funciona upsert en MongoDB con updateOne
Upsert es la fusión entre update e insert. Le indicas a MongoDB que ejecute una actualización y, si el documento no existe, lo cree con los datos del filtro y del update.
La sintaxis es directa: dentro de updateOne agregas un tercer parámetro con upsert: true. [09:15]
js
db.iot.updateOne(
{ sensor: "A0001", date: "2022-01-04" },
{ $push: { readings: 23 } },
{ upsert: true }
)
El flujo se vuelve mucho más limpio:
- Si no existe documento para el sensor
A0001 en la fecha 2022-01-04, MongoDB lo crea con esa primera lectura.
- Si llega una segunda lectura ese mismo día, el mismo método encuentra el documento y agrega el valor al array.
- No tienes que decidir desde tu código si corresponde insert o update.
¿Qué es upsert en MongoDB? Es una bandera del método updateOne que crea el documento si no existe o lo actualiza si ya existe, todo en una sola operación.
¿Upsert funciona con cualquier método de actualización? En esta clase se muestra con updateOne, que es donde se envía la bandera upsert: true para decidir entre crear o modificar el documento.
Un detalle del Playground que te puede confundir
Un punto práctico que aparece al final: el Playground de MongoDB ejecuta el bloque donde tienes el cursor o la selección activa. Si tienes seleccionado un fragmento, solo correrá ese fragmento y puede parecer que tu upsert no se aplicó.
Deja el cursor al final del archivo cuando quieras correr todo, o selecciona conscientemente solo el bloque que te interesa probar. [12:40]
Operadores y conceptos clave de la clase
Para que el modelo y las operaciones funcionen, conviene tener claro cada pieza:
- Colección iot: agrupa los documentos de sensores en Platzi Store. [01:30]
- Modelado un sensor por fecha: garantiza que cada día tenga un único documento por sensor con su array de lecturas. [02:15]
- insertOne: crea el documento completo cuando es la primera lectura del día. [03:50]
- updateOne con $push: agrega una nueva lectura al array
readings de un documento existente. [05:00]
- Operador $pop: elimina el primer (
-1) o último (1) elemento de un array, útil para corregir inserciones equivocadas. [06:45]
- upsert: true: bandera dentro de updateOne que unifica insert y update en una sola llamada. [09:15]
Con esta combinación tu pipeline de IoT escribe menos código, hace menos consultas y mantiene la integridad del modelo: un documento por sensor y por día, con todas sus lecturas dentro.
¿En qué proyecto usarías upsert primero, en sensores, en logs o en perfiles de usuario? Cuéntame en los comentarios cómo lo aplicarías.