Menu Docs

Página inicial do DocsDesenvolver aplicaçõesManual do MongoDB

Adicionar índices secundários às Coleções de séries temporais

Nesta página

  • Use índices secundários para melhorar o desempenho de classificação
  • Últimas Queries de Ponto em Coleções de Séries Temporais
  • Especificar Dicas de Índice para Coleções de Séries Temporais
  • Índices secundários de série temporal no MongoDB 6.0 e posterior

Para melhorar o desempenho da query para coleções de séries temporais, adicione um ou mais índices secundários para suportar padrões de query de séries temporais comuns. 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"] }}

Dica

Veja:

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 } }
] )

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.

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().

Novidades na versão 6.3.

Iniciando no MongoDB 6.3, você pode criar um índice TTL parcial para uma coleção de séries temporais. Você só pode filtrar no metaField.

Se a coleção não usar a opção expireAfterSeconds para expirar documentos, a criação de um índice TTL parcial definirá um tempo de expiração somente para os documentos correspondentes. Se a coleção usar expireAfterSeconds para todos os documentos, um índice TTL parcial permitirá expirar os documentos correspondentes mais cedo.

Novidades na versão 6.0.

A partir do MongoDB 6.0, você pode:

Observação

Se houver coleções de séries temporais e você precisar fazer downgrade da versão de compatibilidade de recursos (FCV), primeiro descartará todos os índices secundários que são incompatíveis com o FCV rebaixado. Consulte setFeatureCompatibilityVersion.

← Definir granularidade para dados de série temporal