Adicionar índices secundários às Coleções de séries temporais
Nesta página
Para melhorar o desempenho da query de coleção de séries temporais, adicione um ou mais índices secundários para dar suporte a padrões comuns de query para coleção de séries temporais. A partir do MongoDB 6.3, O MongoDB cria automaticamente um índice composto nos campos metaField
e timeField
para novas coleções.
Observação
Nem todos os tipos de índice são suportados. Para obter uma lista de tipos de índice sem suporte, consulte Limitações para índices secundários em coleções de séries temporais.
Você pode desejar criar índices secundários adicionais. Considere uma coleção de dados meteorológicos com a configuração:
db.createCollection( "weather", { timeseries: { timeField: "timestamp", metaField: "metadata" }})
Em cada documento de dados meteorológicos, o valor de campo metadata
é um subdocumento com campos para o ID e tipo do sensor meteorológico:
{ "timestamp": ISODate("2021-05-18T00:00:00.000Z"), "metadata": { "sensorId": 5578, "type": "temperature" }, "temp": 12 }
O índice composto padrão para a coleção indexa todo o subdocumento do metadata
, então o índice é utilizado somente com queries do $eq
. Ao indexar campos específicos do metadata
, você melhora o desempenho da query para outros tipos de query.
Por exemplo, esta query do $in
beneficia um índice secundário no metadata.type
:
{ metadata.type:{ $in: ["temperature", "pressure"] }}
Use índices secundários para melhorar o desempenho de classificação
As operações de classificação em coleções de séries temporais podem utilizar índices secundários no campo timeField
. Em certas condições, operações de classificação também podem utilizar índices secundários compostos nos campos metaField
e timeField
.
Os estágios $match
e $sort
do aggregation pipeline determinam quais índices uma coleção de séries temporais pode usar. Um índice pode ser utilizado nos seguintes cenários:
Classificar em
{ <timeField>: ±1 }
utiliza um índice secundário em<timeField>
Classificar em
{ <metaField>: ±1, timeField: ±1 }
usa o índice composto padrão em{ <metaField>: ±1, timeField: ±1 }
A classificação em
{ <timeField>: ±1 }
utiliza um índice secundário em{ metaField: ±1, timeField: ±1 }
quando há um predicado de ponto em<metaField>
Por exemplo, a seguinte coleção sensorData
contém medições de sensores meteorológicos:
db.sensorData.insertMany( [ { "metadata": { "sensorId": 5578, "type": "omni", "location": { type: "Point", coordinates: [-77.40711, 39.03335] } }, "timestamp": ISODate("2022-01-15T00:00:00.000Z"), "currentConditions": { "windDirection": 127.0, "tempF": 71.0, "windSpeed": 2.0, "cloudCover": null, "precip": 0.1, "humidity": 94.0, } }, { "metadata": { "sensorId": 5578, "type": "omni", "location": { type: "Point", coordinates: [-77.40711, 39.03335] } }, "timestamp": ISODate("2022-01-15T00:01:00.000Z"), "currentConditions": { "windDirection": 128.0, "tempF": 69.8, "windSpeed": 2.2, "cloudCover": null, "precip": 0.1, "humidity": 94.3, } }, { "metadata": { "sensorId": 5579, "type": "omni", "location": { type: "Point", coordinates: [-80.19773, 25.77481] } }, "timestamp": ISODate("2022-01-15T00:01:00.000Z"), "currentConditions": { "windDirection": 115.0, "tempF": 88.0, "windSpeed": 1.0, "cloudCover": null, "precip": 0.0, "humidity": 99.0, } } ] )
Crie um índice secundário de campo único no campo timestamp
:
db.sensorData.createIndex( { "timestamp": 1 } )
A seguinte operação de classificação no campo timestamp
utiliza o Índice Secundário para melhorar o desempenho:
db.sensorData.aggregate( [ { $match: { "timestamp" : { $gte: ISODate("2022-01-15T00:00:00.000Z") } } }, { $sort: { "timestamp": 1 } } ] )
Para confirmar que a operação de classificação usou o Índice Secundário, execute a operação novamente com a opção .explain( "executionStats" )
:
db.sensorData.explain( "executionStats" ).aggregate( [ { $match: { "timestamp": { $gte: ISODate("2022-01-15T00:00:00.000Z") } } }, { $sort: { "timestamp": 1 } } ] )
Últimas Queries de Ponto em Coleções de Séries Temporais
Em dados de série temporal, a mais recente query de ponto gera o ponto de dados com o carimbo de data/hora mais recente para um determinado campo. Para coleções de séries temporais, a mais recente query de ponto obtém a medição mais recente para cada valor de metadados único. Por exemplo, para obter a leitura de temperatura mais recente de todos os sensores. Aprimore o desempenho das mais recentes queries de ponto criando qualquer um dos seguintes índices:
{ "metadata.sensorId": 1, "timestamp": 1 } { "metadata.sensorId": 1, "timestamp": -1 } { "metadata.sensorId": -1, "timestamp": 1 } { "metadata.sensorId": -1, "timestamp": -1 }
Observação
As últimas queries de ponto têm o maior desempenho quando usam a otimização DISTINCT_SCAN. Esta otimização só está disponível quando um índice em timeField
é descendente.
O seguinte comando cria um índice secundário composto no metaField
(ascendente) e timeField
(descendente):
db.sensorData.createIndex( { "metadata.sensorId": 1, "timestamp": -1 } )
O último exemplo de query de ponto seguinte utiliza o índice secundário composto timeField
descendente criado acima:
db.sensorData.aggregate( [ { $sort: { "metadata.sensorId": 1, "timestamp": -1 } }, { $group: { _id: "$metadata.sensorId", ts: { $first: "$timestamp" }, temperatureF: { $first: "$currentConditions.tempF" } } } ] )
Para confirmar que a mais recente query de ponto utilizou o índice secundário, execute a operação novamente utilizando .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" } } } ] )
O winningPlan.queryPlan.inputStage.stage
é DISTINCT_SCAN
, o que indica que o índice foi utilizado. Para obter mais informações sobre a saída do plano de explicação, consulte Explicar resultados.
Especificar Dicas de Índice para Coleções de Séries Temporais
Sugestões de índice fazem com que MongoDB use um índice específico para uma query. Algumas operações em coleções de séries temporais só podem tirar proveito de um índice se esse índice for especificado em uma dica.
Por exemplo, a seguinte query faz com que MongoDB utilize o índice timestamp_1_metadata.sensorId_1
:
db.sensorData.find( { "metadata.sensorId": 5578 } ).hint( "timestamp_1_metadata.sensorId_1" )
Em uma coleção de séries temporais, você pode especificar dicas usando o nome do índice ou o padrão da chave do índice. Para obter os nomes dos índices em uma coleção, utilize o método db.collection.getIndexes()
.
Criar índices 2dsphere
A partir da versão 6.0, você pode criar índices 2dsphere nos campos timeField
, metaField
ou de medição.
Por exemplo, a operação a seguir cria um índice 2dsphere no campo location
:
Exemplo
db.sensorData.createIndex({ "metadata.location": "2dsphere" })
Além disso, a operação a seguir cria um índice 2dsphere nos campos de medição:
Exemplo
db.sensorData.createIndex({ "currentConditions.tempF": "2dsphere" })
Observação
Se houver índices secundários em coleções de séries temporais e você precisar fazer downgrade da versão de compatibilidade de recursos (FCV), primeiro deverá descartar todos os índices secundários que são incompatíveis com o FCV rebaixado. Para mais informações, consulte setFeatureCompatibilityVersion
.