Volver a MongoDB Intermedio

Colecciones de Series Temporales en MongoDB

Crear una Colección Time Series

db.createCollection("datosSensores", { timeseries: { timeField: "timestamp", // obligatorio: campo ISODate metaField: "sensorId", // opcional: identifica la fuente granularity: "seconds" // seconds | minutes | hours }, expireAfterSeconds: 86400 * 90 // eliminar automáticamente a los 90 días })

Insertar Datos

// Insertar una lectura await db.collection("datosSensores").insertOne({ timestamp: new Date(), sensorId: "sensor-001", ubicacion: "almacen-A", lecturas: { temperatura: 22.5, humedad: 65.3, presion: 1013.25 } }) // Inserción masiva eficiente const lecturas = Array.from({ length: 1000 }, (_, i) => ({ timestamp: new Date(Date.now() - i * 1000), sensorId: "sensor-001", lecturas: { temperatura: 20 + Math.random() * 5 } })) await db.collection("datosSensores").insertMany(lecturas)

Consultar Series Temporales

// Consulta por rango (usa agrupación temporal interna) db.datosSensores.find({ sensorId: "sensor-001", timestamp: { $gte: new Date("2024-01-01"), $lt: new Date("2024-02-01") } }) // Agregación con cubos temporales (promedio por hora) db.datosSensores.aggregate([ { $match: { sensorId: "sensor-001", timestamp: { $gte: new Date("2024-01-01") } } }, { $group: { _id: { $dateTrunc: { date: "$timestamp", unit: "hour" } }, tempPromedio: { $avg: "$lecturas.temperatura" }, tempMaxima: { $max: "$lecturas.temperatura" }, tempMinima: { $min: "$lecturas.temperatura" } } }, { $sort: { _id: 1 } } ])

$setWindowFields: Medias Móviles

db.datosSensores.aggregate([ { $match: { sensorId: "sensor-001" } }, { $sort: { timestamp: 1 } }, { $setWindowFields: { partitionBy: "$sensorId", sortBy: { timestamp: 1 }, output: { mediaMovil5min: { $avg: "$lecturas.temperatura", window: { range: [-5, 0], unit: "minute" } }, totalAcumulado: { $sum: "$lecturas.temperatura", window: { documents: ["unbounded", "current"] } } } } } ])

Buenas Prácticas

// 1. Filtrar siempre por metaField y rango temporal primero db.datosSensores.find({ sensorId: "sensor-001", // metaField (indexado) timestamp: { $gte: inicio } // timeField (agrupado) }) // 2. Elegir granularity según la frecuencia de muestreo // - "seconds": datos cada pocos segundos // - "minutes": datos cada pocos minutos // - "hours": datos cada pocas horas // 3. Configurar TTL para gestionar almacenamiento db.createCollection("metricas", { timeseries: { timeField: "ts", metaField: "host" }, expireAfterSeconds: 86400 * 30 // 30 días })