Join us at MongoDB.local London on 7 May to unlock new possibilities for your data. Use WEB50 to save 50%.
Register now >
Docs Menu
Docs Home
/ /

mejores prácticas para colección de series de tiempo

Esta página describe las mejores prácticas para mejorar el rendimiento y el uso de datos en colecciones de series de tiempo.

Para optimizar la compresión de datos para colecciones de series temporales, realice las siguientes acciones:

Si tus datos contienen objetos, arreglos o cadenas vacías, omite los campos vacíos de tus documentos para optimizar la compresión.

Por ejemplo, considere los siguientes documentos:

{
timestamp: ISODate("2020-01-23T00:00:00.441Z"),
coordinates: [1.0, 2.0]
},
{
timestamp: ISODate("2020-01-23T00:00:10.441Z"),
coordinates: []
},
{
timestamp: ISODate("2020-01-23T00:00:20.441Z"),
coordinates: [3.0, 5.0]
}

coordinates Los campos con valores rellenados y los campos coordinates con una matriz vacía generan un cambio de esquema en el compresor. Este cambio hace que el segundo y el tercer documento de la secuencia permanezcan sin comprimir.

Optimiza la compresión omitiendo los campos con valores vacíos, como se muestra en los siguientes documentos:

{
timestamp: ISODate("2020-01-23T00:00:00.441Z"),
coordinates: [1.0, 2.0]
},
{
timestamp: ISODate("2020-01-23T00:00:10.441Z")
},
{
timestamp: ISODate("2020-01-23T00:00:20.441Z"),
coordinates: [3.0, 5.0]
}

Redondea los datos numéricos a la precisión que requiere tu aplicación. Redondear los datos numéricos a menos decimales mejora la relación de compresión.

If an modelo de datos incrustado para satisfacer las necesidades de tu aplicación, usa campos anidados. El comportamiento de los campos anidados no difiere entre las colecciones regulares y las colecciones de series temporales.

Por ejemplo, considera una colección de series de tiempo que contenga documentos meteorológicos similares al siguiente ejemplo:

{
timestamp: ISODate("2024-06-17T10:00:00Z"),
stationId: "ALPHA123",
atmosphere: {
temperature: 21.5,
humidity: 68,
pressure: 1013.25
},
wind: {
speed: 7.2,
direction: "NW"
},
precipitation: 0.5,
visibility: 10
}

MongoDB utiliza compresión por columnas en cada campo anidado de forma individual, lo que ofrece la misma calidad de compresión que al aplanar los campos al nivel superior. La compresión resultante es idéntica a la compresión que resultaría de aplanar todos los campos anidados a campos de nivel superior.

Importante

La compresión de columnas requiere un orden de campos anidados consistente. Sin embargo, si utiliza un controlador para interactuar con sus datos, puede haber consideraciones de ordenación adicionales. Por ejemplo, consulte BSON types para consideraciones sobre la representación ordenada del controlador de Go. Consulta la documentación del controlador para obtener más información.

Si su carga de trabajo tiene una alta cardinalidad, aplanar objetos anidados puede mejorar el rendimiento. Por ejemplo, el siguiente documento contiene los mismos datos que el documento anterior, pero en un formato simplificado:

{
timestamp: ISODate("2024-06-17T10:00:00Z"),
stationId: "ALPHA123",
atmosphere_temperature: 21.5,
atmosphere_humidity: 68,
atmosphere_pressure: 1013.25
wind_speed: 7.2,
wind_direction: "NW"
precipitation: 0.5,
visibility: 10
}

Nota

Use un modelo de datos que sea más natural para tu aplicación. MongoDB solo recomienda aplanar documentos si una estructura anidada causa problemas de rendimiento significativos.

Para optimizar el rendimiento de inserción de colecciones de series temporales, realice las siguientes acciones:

Al insertar varios documentos:

  • Para evitar viajes de ida y vuelta a la red, utiliza una única insertMany() instrucción en lugar de varias insertOne() instrucciones.

  • Si es posible, inserte datos que contengan valores idénticos de metaField en los mismos lotes.

  • Establezca el parámetro ordered en false.

Por ejemplo, si tiene dos sensores que corresponden a dos valores metaField, sensor A y sensor B, un lote que contiene múltiples mediciones de un solo sensor incurre en el costo de una inserción, en lugar de una inserción por medición.

La siguiente operación inserta seis documentos, pero sólo incurre en el costo de dos inserciones (una por cada valor de metaField), porque los documentos están ordenados por sensor. El parámetro ordered se establece en false para mejorar el rendimiento:

db.temperatures.insertMany(
[
{
metaField: {
sensor: "sensorA"
},
timestamp: ISODate("2021-05-18T00:00:00.000Z"),
temperature: 10
},
{
metaField: {
sensor: "sensorA"
},
timestamp: ISODate("2021-05-19T00:00:00.000Z"),
temperature: 12
},
{
metaField: {
sensor: "sensorA"
},
timestamp: ISODate("2021-05-20T00:00:00.000Z"),
temperature: 13
},
{
metaField: {
sensor: "sensorB"
},
timestamp: ISODate("2021-05-18T00:00:00.000Z"),
temperature: 20
},
{
metaField: {
sensor: "sensorB"
},
timestamp: ISODate("2021-05-19T00:00:00.000Z"),
temperature: 25
},
{
metadField: {
sensor: "sensorB"
},
timestamp: ISODate("2021-05-20T00:00:00.000Z"),
temperature: 26
}
],
{ "ordered": false }
)

Usar un orden de campos coherente en tus documentos mejora el rendimiento de inserción y compresión.

Nota

La compresión requiere un orden coherente de los campos anidados. Para obtener más información sobre la compresión con campos anidados, consulte Prácticas recomendadas para campos anidados.

Por ejemplo, insertar los siguientes documentos, todos los cuales tienen el mismo orden de campos, da como resultado un rendimiento óptimo.

{
_id: ObjectId("6250a0ef02a1877734a9df57"),
timestamp: ISODate("2020-01-23T00:00:00.441Z"),
name: "sensor1",
range: 1
},
{
_id: ObjectId("6560a0ef02a1877734a9df66"),
timestamp: ISODate("2020-01-23T01:00:00.441Z"),
name: "sensor1",
range: 5
}

Por el contrario, los siguientes documentos no alcanzan un rendimiento óptimo, porque sus órdenes de campo difieren:

{
range: 1,
_id: ObjectId("6250a0ef02a1877734a9df57"),
name: "sensor1",
timestamp: ISODate("2020-01-23T00:00:00.441Z")
},
{
_id: ObjectId("6560a0ef02a1877734a9df66"),
name: "sensor1",
timestamp: ISODate("2020-01-23T01:00:00.441Z"),
range: 5
}

Aumentar la cantidad de clientes que escriben datos en sus colecciones puede mejorar el rendimiento.

Para optimizar la fragmentación en su colección de series temporales, realice la siguiente acción:

Utilizar el metaField para particionar tu colección proporciona una cardinalidad suficiente como clave de partición para colecciones de series de tiempo.

Para optimizar las consultas en su colección de series temporales, realice las siguientes acciones:

La elección de metaField tiene el mayor impacto en la optimización de las consultas en tu aplicación.

  • Selecciona los campos que casi nunca o nunca cambian como parte de tu metaField.

  • Si es posible, selecciona identificadores u otros valores estables que sean frecuentes en las expresiones de filtro como parte de tu metaField.

  • Evita seleccionar campos que no se usen para filtro como parte de tu metaField. En su lugar, utiliza esos campos como mediciones.

Para obtener más información, consulta metaField Considerations.

Cuando se crea una colección de series de tiempo, MongoDB agrupa los datos de series de tiempo entrantes en buckets. Al establecer correctamente la granularidad, tienes control sobre la frecuencia con la que los datos se agrupan en función de la tasa de ingesta de tus datos.

A partir de MongoDB 6.3, puede usar los parámetros de agrupación personalizados bucketMaxSpanSeconds y bucketRoundingSeconds para especificar los límites de los grupos y controlar con mayor precisión cómo se agrupan los datos de series de tiempo.

Puedes mejorar el rendimiento configurando los parámetros de agrupamiento granularity o personalizados para que coincidan lo mejor posible con el intervalo de tiempo entre las mediciones entrantes de la misma fuente de datos. Por ejemplo, si se están registrando datos meteorológicos de miles de sensores, pero solo se registran datos de cada sensor una vez cada 5 minutos, se puede configurar granularity a "minutes" o establecer los parámetros de agrupación personalizada a 300 (segundos).

En este caso, configurar el campo granularity en hours agrupa hasta un mes de eventos de data ingest en un solo bucket, lo que resulta en tiempos de recorrido más largos y consultas más lentas. Establecerlo en seconds conduce a múltiples buckets por intervalo de sondeo, muchos de los cuales podrían contener solo un único documento.

La siguiente tabla muestra el intervalo de tiempo máximo incluido en un bucket de datos cuando se usa un determinado valor granularity:

granularity
granularity límite de bucket

seconds

1 hora

minutes

24 horas

hours

30 días

Tip

Para mejorar el rendimiento de las consultas, cree uno o más índices secundarios en timeField y metaField para que admitan patrones de consulta comunes. En las versiones 6.3 y posteriores, MongoDB crea automáticamente un índice secundario en timeField metaField y.

  • Use el índice metaField para el filtro y la igualdad.

  • Utilice timeField y otros campos indexados para consultas de rango.

  • Las estrategias generales de indexación también aplican a las colecciones de series temporales. Para más información, consulta Estrategias de indexación.

MongoDB reorganiza el metaField de las colecciones de series temporales, lo que puede hacer que los servidores almacenen los datos en un orden de campo diferente al de las aplicaciones. Si un metaField es un objeto, las consultas en el metaField pueden producir resultados inconsistentes debido a que el orden metaField puede variar entre servidores y aplicaciones. Para optimizar las queries en una metaField de serie de tiempo, query el metaField en subcampos escalares en lugar de query todo el metaField.

El siguiente ejemplo crea una colección de series de tiempo:

db.weather.insertMany( [
{
metaField: { sensorId: 5578, type: "temperature" },
timestamp: ISODate( "2021-05-18T00:00:00.000Z" ),
temp: 12
},
{
metaField: { sensorId: 5578, type: "temperature" },
timestamp: ISODate( "2021-05-18T04:00:00.000Z" ),
temp: 11
}
] )

La siguiente consulta en los subcampos escalares sensorId y type devuelve el primer documento que coincide con los criterios de consulta:

db.weather.findOne( {
"metaField.sensorId": 5578,
"metaField.type": "temperature"
} )

Ejemplo de salida:

{
_id: ObjectId("6572371964eb5ad43054d572"),
metaField: { sensorId: 5578, type: 'temperature' },
timestamp: ISODate( "2021-05-18T00:00:00.000Z" ),
temp: 12
}

Debido a la estructura única de datos de las colecciones de series temporales, MongoDB no puede indexarlas eficientemente para valores distintos. Evite utilizar el comando distinct o el método asistente db.collection.distinct() en colecciones de series temporales. En su lugar, use una $group agregación para agrupar documentos por valores distintos.

Por ejemplo, para query valores meta.type distintos en documentos donde meta.project = 10, en lugar de:

db.foo.distinct("meta.type", {"meta.project": 10})

Uso:

db.foo.createIndex({"meta.project":1, "meta.type":1})
db.foo.aggregate([{$match: {"meta.project": 10}},
{$group: {_id: "$meta.type"}}])

Esto funciona de la siguiente manera:

  1. Creando un índice compuesto en meta.project y meta.type y admite la agregación.

  2. La etapa $match filtra los documentos en los que meta.project = 10.

  3. La etapa $group utiliza meta.type como la clave de grupo para generar un documento por cada valor único.

Volver

Agregar índices secundarios