Menu Docs
Página inicial do Docs
/
Manual do MongoDB
/

Melhores práticas para Coleções de séries temporais

Nesta página

  • Otimizar inserções
  • Gravações de documentos em lote
  • Usar ordem de campo consistente em documentos
  • Aumentar o número de clientes
  • Otimizar compressão
  • Campos de omissão contendo objetos vazios e arrays de documentos
  • Arredondar dados numéricos para poucos locais decimais
  • Otimizar o desempenho da consulta
  • Definir a granularidade apropriada do bucket
  • Criar índices secundários
  • Query de metaFields em subcampos
  • Use $group em vez de Distinct()

Esta página descreve as melhores práticas para melhorar o desempenho e o uso de dados para coleções de séries temporais.

Para otimizar o desempenho de inserção para coleções de séries temporais, execute as seguintes ações.

Ao inserir vários documentos:

Por exemplo, se você tiver dois sensores, sensor A e sensor B, um lote contendo múltiplas medições de um único sensor incorrerá no custo de uma inserção, em vez de uma inserção por medida.

A operação a seguir insere seis documentos, mas só incorre no custo de duas inserções (uma por lote), pois os documentos são ordenados por sensor. O parâmetro ordered está configurado para false para melhorar o desempenho:

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

Usar uma ordem de campo consistente em seus documentos melhora o desempenho da inserção.

Por exemplo, a inserção destes documentos proporciona um desempenho de inserção ideal:

{
"_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 outro lado, esses documentos não alcançam o desempenho ideal de inserção, porque suas ordens de campo diferem:

{
"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 o número de clientes que gravam dados em suas coleções pode melhorar o desempenho.

Para otimizar a compressão de dados para coleções de séries temporais, execute as seguintes ações.

Para otimizar a compressão, se os dados contiverem objetos ou arrays vazios, omita os campos vazios dos documentos.

Por exemplo, considere os seguintes 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]
}

A alternância entre campos coordinates com valores preenchidos e uma array vazia resulta em uma alteração de esquema para o compressor. A mudança de esquema faz com que o segundo e o terceiro documentos da sequência permaneçam descompactados.

Em contraste, os seguintes documentos em que a array vazia é omitida recebem o benefício da compressão ideal:

{
"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]
}

Arredonde os dados numéricos com a precisão necessária para sua aplicação. O arredondamento dos dados numéricos para menos casas decimais melhora a taxa de compactação.

Quando você cria uma coleção de séries temporais, o MongoDB agrupa os dados de série temporal recebidos em buckets. Ao definir com precisão a granularidade, você controla a frequência com que os dados são colocados em buckets com base na taxa de ingestão de seus dados.

A partir do MongoDB 6.3, você pode usar os parâmetros de bucketing personalizados bucketMaxSpanSeconds e bucketRoundingSeconds para especificar os limites do bucket e controlar com mais precisão como os dados de série temporal são compartimentados.

Você pode melhorar o desempenho definindo os parâmetros de bucketing granularity ou personalizados para a melhor correspondência referente ao intervalo de tempo entre as medições recebidas da mesma fonte de dados. Por exemplo, ao gravar dados meteorológicos com milhares de sensores, e apenas gravar dados de cada sensor uma vez a cada 5 minutos, você pode definir a granularity em "minutes" ou definir os parâmetros de bucketing personalizados para 300 (segundos).

Neste caso, definir a granularity em hours junta até um mês de eventos de ingestão de dados em um único bucket, resultando em tempos de travessia mais longos e queries mais lentas. Configurá-la como seconds resulta em vários buckets por intervalo de sondagem, muitos dos quais podem conter somente um único documento.

A tabela abaixo mostra o intervalo de tempo máximo incluído em um bucket de dados ao utilizar um determinado valor granularity:

granularity
granularity limite de bucket
seconds
1 hora
minutes
24 horas
hours
30 dias

Dica

Veja também:

Para melhorar o desempenho da query, crie um ou mais índices secundários no seu timeField e metaField para suportar padrões de query comuns. Nas versões 6.3 e superior, o MongoDB cria automaticamente um índice secundário no timeField e no metaField.

O MongoDB reordena os metaFields de coleções de séries temporais, o que pode fazer com que os servidores armazenem dados em uma ordem de campo diferente dos aplicativos. Se metaFields forem objetos, queries em metaFields inteiros podem produzir resultados inconsistentes, pois a ordem de metaField pode variar entre servidores e aplicativos. Para otimizar queries em metaFields de séries temporais, consulte timeseries metaFields em subcampos escalares em vez de metaFields inteiros.

O exemplo a seguir cria uma coleção de séries temporais:

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

A seguinte query nos subcampos escalares sensorId e type retorna o primeiro documento que corresponde aos critérios da query:

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

Saída de exemplo:

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

Devido à estrutura de dados única das coleções de séries temporais, o MongoDB não pode indexá-las de forma eficiente para valores diferentes. Evite usar o comando distinct ou método assistente db.collection.distinct() em coleções de séries temporais. Em vez disso, use uma agregação $group para agrupar documentos por valores distintos.

Por exemplo, para consultar valores meta.type diferentes em documentos onde meta.project = 10, em vez de:

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

Usar:

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

Isso funciona da seguinte maneira:

  1. Criando um índice composto em meta.project e meta.type e é compatível com a agregação.

  2. O estágio $match filtra documentos onde meta.project = 10.

  3. O estágio $group usa meta.type como a chave de grupo para gerar um documento por valor exclusivo.

Voltar

Fragmentar uma Coleção de séries temporais