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

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

Nesta página

  • Práticas recomendadas de compressão
  • Campos de omissão contendo objetos vazios e arrays de documentos
  • Arredondar dados numéricos para poucos locais decimais
  • Insere Melhores Práticas
  • Gravações de documentos em lote
  • Usar ordem de campo consistente em documentos
  • Aumentar o número de clientes
  • Práticas recomendadas de compartilhamento
  • Use o metaField como sua chave de fragmento
  • Práticas recomendadas de query
  • Defina um metaField estratégico ao criar a collection
  • Definir a granularidade apropriada do bucket
  • Criar índices secundários
  • Práticas recomendadas de índices adicionais
  • Consulte o metaField 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 a compressão de dados para coleções de séries temporais, execute as seguintes ações:

Se seus dados contiverem objetos, arrays ou strings vazios, omita os campos vazios dos documentos para otimizar a compressão.

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

coordinates campos com valores preenchidos e campos coordinates com uma array vazia resultam 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.

Otimize a compressão omitindo os campos com valores vazios, conforme mostrado nos seguintes 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]
}

Arredonde os dados numéricos com a precisão que sua aplicação exige. Arredondar dados numéricos com menos casas decimais melhora a taxa de compressão.

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

Ao inserir vários documentos:

  • Para evitar viagens de ida e volta de rede, use um único insertMany() em vez de vários comandos insertOne() .

  • Se possível, insira dados que contenham valores de metaField idênticos nos mesmos lotes.

  • Configure o parâmetro ordered para false.

Por exemplo, se você tiver dois sensores que correspondem a dois valores metaField , sensor A e sensor B, um lote que contém 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 valor metaField ), pois os documentos são ordenados por sensor. O parâmetro ordered é definido como false para melhorar o desempenho:

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 uma ordem de campo consistente em seus documentos melhora o desempenho da inserção.

Por exemplo, inserir os seguintes documentos, todos os quais têm a mesma ordem de campo , resulta em 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, os documentos a seguir 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 collections pode melhorar o desempenho.

Para otimizar a fragmentação em sua coleção de séries temporais, execute a seguinte ação:

Usar metaField para fragmentar sua collection fornece cardinalidade suficiente como uma chave de shard para coleções de séries temporais.

Observação

A partir do MongoDB 8.0, o uso do timeField como uma chave de shard em coleções de séries temporais é preterido.

Para otimizar as queries em sua coleção de séries temporais, execute as seguintes ações:

Sua escolha do metaField tem o maior impacto na otimização de consultas em seu aplicação.

  • Selecione campos que raramente ou nunca mudam como parte do seu metaField.

  • Se possível, selecione identificadores ou outros valores estáveis que são comuns em expressões de filtro como parte do seu metaField.

  • Evite selecionar campos que não são usados para filtragem como parte do seu metaField. Em vez disso, use esses campos como medições.

Para obter mais informações, consulte Considerações sobre metaField.

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.

  • Use o índice metaField para filtragem e igualdade.

  • Use o timeField e outros campos indexados para queries de intervalo.

  • Estratégias gerais de indexação também se aplicam a coleções de séries temporais. Para obter mais informações, consulte Indexação de estratégias.

O MongoDB reordena o metaField das coleções de séries temporais, o que pode fazer com que os servidores armazenem dados em uma ordem de campo diferente da dos aplicativos. Se um metaField for um objeto, as consultas no metaField poderão produzir resultados inconsistentes porque a ordem do metaField pode variar entre servidores e aplicativos. Para otimizar as queries em uma série temporal metaField, consulte o metaField em subcampos escalares em vez de todo o metaField.

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 exclusiva das coleções de séries temporais, o MongoDB não pode indexá-las com eficiência para valores distintos. Evite usar o comando distinct ou o 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 fazer query de valores meta.type distintos 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 forma:

  1. Cria um índice composto em meta.project e meta.type e oferece suporte à agregação.

  2. Os filtros de estágio $match para documentos onde meta.project = 10.

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

Voltar

Adicionar índices secundários