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

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

Nesta página

  • Melhores práticas de compactaçã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
  • Melhores práticas de fragmentação
  • Use o metaField como sua chave de fragmento
  • Práticas recomendadas de query
  • Defina um metaField estratégico ao criar a coleção
  • Definir a granularidade apropriada do bucket
  • Criar índices secundários
  • Práticas recomendadas adicionais de índice
  • Fazer query nos subcampos metaField
  • 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 compactaçã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 compactaçã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 compactação omitindo os campos com valores em branco, 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 seu aplicativo exige. O arredondamento dos dados numéricos para menos casas decimais melhora a taxa de compactaçã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 idas e vindas da rede, use um único comando insertMany() em vez de vários comandos insertOne().

  • Se possível, insira dados que contenham valores 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 várias medições de um único sensor incorre no custo de um inserto, em vez de um inserto por medição.

A operação a seguir insere seis documentos, mas incorre apenas no custo de duas inserções (uma por cada valor metaField), pois os documentos são ordenados por sensor. O parâmetro ordered está configurado para 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, a inserção dos seguintes documentos, todos com a mesma ordem de campos, resulta em 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, os documentos a seguir não atingem o desempenho ideal de inserção, pois suas ordens de campo são diferentes:

{
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 fragmentação na sua coleção de séries temporais, execute a seguinte ação:

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

Observação

A partir do MongoDB 8.0, o uso de timeField como uma chave de fragmento em coleções de séries temporais será descontinuado.

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

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

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

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

  • Evite selecionar campos que não sejam usados para filtragem como parte do seu MetaField. Em vez disso, use esses campos como medidas.

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 consultas de intervalo.

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

O MongoDB reordena os metaField 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 um metaField for um objeto, as queries no metaField podem produzir resultados inconsistentes porque a ordem metaField pode variar entre servidores e aplicativos. Para otimizar queries em uma série temporal metaField, faça query em subcampos escalares metaField em vez de em 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 ú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

Adicione índices secundários