Para mejorar el rendimiento de las consultas En las colecciones de series temporales, agregue uno o más índices secundarios para admitir patrones comunes de consulta de series temporales. En concreto, recomendamos crear uno o más índices compuestos en los campos especificados como timeField y el metaField. Si el valor del metaField campo es un documento, puedes crear índices secundarios en campos dentro de ese documento.
Nota
No todos los tipos de índices son compatibles. Para obtener una lista de tipos de índices no admitidos, consulte Limitaciones para índices secundarios en colecciones de series de tiempo.
Por ejemplo, este comando crea un índice compuesto en los campos metadata.sensorId y timestamp:
db.weather24h.createIndex( { "metadata.sensorId": 1, "timestamp": 1 } )
Utiliza índices secundarios para mejorar el rendimiento de clasificación
Las colecciones de Series Temporales pueden usar índices para mejorar el rendimiento de clasificación en el timeField y el metaField.
Por ejemplo, la siguiente colección sensorData contiene mediciones de sensores meteorológicos:
db.sensorData.insertMany( [ { "metadata": { "sensorId": 5578, "location": { type: "Point", coordinates: [-77.40711, 39.03335] } }, "timestamp": ISODate("2022-01-15T00:00:00.000Z"), "currentConditions": { "windDirecton": 127.0, "tempF": 71.0, "windSpeed": 2.0, "cloudCover": null, "precip": 0.1, "humidity": 94.0, } }, { "metadata": { "sensorId": 5578, "location": { type: "Point", coordinates: [-77.40711, 39.03335] } }, "timestamp": ISODate("2022-01-15T00:01:00.000Z"), "currentConditions": { "windDirecton": 128.0, "tempF": 69.8, "windSpeed": 2.2, "cloudCover": null, "precip": 0.1, "humidity": 94.3, } }, { "metadata": { "sensorId": 5579, "location": { type: "Point", coordinates: [-80.19773, 25.77481] } }, "timestamp": ISODate("2022-01-15T00:01:00.000Z"), "currentConditions": { "windDirecton": 115.0, "tempF": 88.0, "windSpeed": 1.0, "cloudCover": null, "precip": 0.0, "humidity": 99.0, } } ] )
Las colecciones de series temporales crean automáticamente un índice agrupado interno. El planificador de query utiliza este índice para mejorar el rendimiento de ordenación.
Nota
Si insertas un documento en una colección con un valor de timeField antes de 1970-01-01T00:00:00.000Z o después de 2038-01-19T03:14:07.000Z, MongoDB registra una advertencia e impide que algunas optimizaciones de query utilicen el índice interno. Cree un índice secundario en el timeField para recuperar el rendimiento de las consultas y resolver la advertencia en los registros.
La siguiente operación de ordenamiento en el campo timestamp utiliza el índice agrupado para mejorar el rendimiento:
db.sensorData.find().sort( { "timestamp": 1 } )
Para confirmar que la operación de ordenamiento utilizó el índice agrupado, ejecute la operación nuevamente con la opción .explain( "executionStats" ):
db.sensorData.find().sort( { "timestamp": 1 } ).explain( "executionStats" )
El winningPlan.queryPlan.inputStage.stage es COLLSCAN y una etapa _internalBoundedSort está presente en la salida del plan de explicación. El campo interalBoundedSort indica que se utilizó el índice agrupado. Para obtener más información sobre la salida del plan de explique, consulta resultados de explique.
Los índices secundarios sobre las colecciones de series temporales pueden mejorar el rendimiento de las operaciones de ordenación y aumentar el número de escenarios en los que se pueden utilizar índices.
La operación de ordenamiento en la colección de series de tiempo puede utilizar el índice secundario en el timeField. Bajo ciertas condiciones, las operaciones de ordenación también pueden utilizar índices secundarios compuestos en metaField y timeField.
Las etapas del pipeline de agregación $match y $sort determinan qué índices puede utilizar una colección de series de tiempo. La siguiente lista describe los escenarios en los que puede utilizarse un índice:
El ordenamiento en
{ <timeField:> ±1 }utiliza el índice agrupadoEl ordenamiento en
{ <timeField>: ±1 }utiliza un índice secundario en<timeField>El ordenamiento en
{ <metaField>: ±1, timeField: ±1 }utiliza un índice secundario en{ <metaField>: ±1, timeField: ±1 }La ordenación en
{ <timeField>: ±1 }utiliza un índice secundario en{ metaField: ±1, timeField: ±1 }cuando existe un predicado puntual en<metaField>
Crea un índice secundario en el campo timestamp:
db.sensorData.createIndex( { "timestamp": 1 } )
La siguiente operación de clasificación en el campo timestamp utiliza el índice secundario para mejorar el rendimiento:
db.sensorData.aggregate( [ { $match: { "timestamp" : { $gte: ISODate("2022-01-15T00:00:00.000Z") } } }, { $sort: { "timestamp": 1 } } ] )
Para confirmar que la operación de ordenación utilizó el índice Secundario, ejecute la operación nuevamente con la opción .explain( "executionStats" ):
db.sensorData.explain( "executionStats" ).aggregate( [ { $match: { "timestamp": { $gte: ISODate("2022-01-15T00:00:00.000Z") } } }, { $sort: { "timestamp": 1 } } ] )
Consultas de "último punto" en colecciones de series temporales
Una consulta de "último punto" obtiene la última medición de cada valor de metadatos único. Por ejemplo, podría querer obtener la última lectura de temperatura de todos los sensores. Mejore el rendimiento de las consultas de último punto creando cualquiera de los siguientes índices:
{ "metadata.sensorId": 1, "timestamp": 1 } { "metadata.sensorId": 1, "timestamp": -1 } { "metadata.sensorId": -1, "timestamp": 1 } { "metadata.sensorId": -1, "timestamp": -1 }
Nota
Las consultas de último punto son más eficientes cuando utilizan la optimización DISTINCT_SCAN. Esta optimización solo está disponible cuando existe un índice descendente en timeField.
El siguiente comando crea un índice secundario compuesto en metaField (ascendente) y timeField (descendente):
db.sensorData.createIndex( { "metadata.sensorId": 1, "timestamp": -1 } )
El siguiente ejemplo de query de último punto utiliza el índice secundario compuesto descendente timeField creado anteriormente:
db.sensorData.aggregate( [ { $sort: { "metadata.sensorId": 1, "timestamp": -1 } }, { $group: { _id: "$metadata.sensorId", ts: { $first: "$timestamp" }, temperatureF: { $first: "$currentConditions.tempF" } } } ] )
Para confirmar que la última consulta de punto utilizó el índice secundario, ejecute la operación nuevamente usando .explain( "executionStats" ):
db.getCollection( 'sensorData' ).explain( "executionStats" ).aggregate( [ { $sort: { "metadata.sensorId": 1, "timestamp": -1 } }, { $group: { _id: "$metadata.sensorId", ts: { $first: "$timestamp" }, temperatureF: { $first: "$currentConditions.tempF" } } } ] )
El winningPlan.queryPlan.inputStage.stage es DISTINCT_SCAN, lo que indica que se utilizó el índice. Para obtener más información sobre la salida del plan de explicación, consulta Explicar resultados.
Especificar sugerencias de índice para colecciones de series de tiempo
Las sugerencias de índice hacen que MongoDB utilice un índice específico para una query. Algunas operaciones en colecciones de series temporales sólo pueden aprovechar un índice si ese índice se especifica en una indicación.
Por ejemplo, la siguiente consulta hace que MongoDB utilice el índice timestamp_1_metadata.sensorId_1:
db.sensorData.find( { "metadata.sensorId": 5578 } ).hint( "timestamp_1_metadata.sensorId_1" )
En una colección de series de tiempo, puedes especificar sugerencias usando el nombre del índice o el patrón de clave del índice. Para obtener los nombres de los índices en una colección, utiliza el método db.collection.getIndexes().
Índices secundarios de series de tiempo en MongoDB 6.0
A partir de MongoDB 6.0, puedes:
Agrega un índice compuesto en los campos
timeField,metaFieldo de medición.Utiliza los
$or,$iny$geoWithinoperadores con índices parciales en una colección de series de tiempo.Añade un índice parcial
metaFieldentimeFieldy.Agregue un índice secundario a cualquier campo o subcampo.
Utilice
metaFieldcon índices 2dsphere.
Nota
Si hay índices secundarios en colecciones de series de tiempo y necesitas degradar la versión de compatibilidad de funciones (FCV), primero debes descartar cualquier índice secundario que sea incompatible con la FCV degradada. Para obtener más información, consulta setFeatureCompatibilityVersion.