MongoDB时间序列

一、概述

时间序列数据是一系列数据点,通过分析随时间的变化可以获得见解。
时间序列数据通常由以下组成部分组成:

  • 记录数据点的时间。
  • 元数据(有时称为源),它是一个标签或标记,用于唯一标识一个系列,并且很少更改。
  • 测量(有时称为度量或值),是以时间增量跟踪的数据点。通常,这些是随时间变化的键值对。

下表显示了时间序列数据的示例:

Example

Measurement

Metadata

Stock data

Stock price

Stock ticker, exchange

Weather data

Temperature

Sensor identifier, location

Website visitors

View count

URL

为了高效地存储时间序列数据,MongoDB提供了时间序列集合。 

1、时序集合

5.0版新增。
时间序列集合有效地存储时间序列数据。在时间序列集合中,对写入进行组织,以便将来自同一源的数据与来自类似时间点的其他数据点一起存储。
好处
与普通集合相比,将时间序列数据存储在时间序列集合中提高了查询效率,并减少了时间序列数据和二级索引的磁盘使用量。
时间序列集合使用底层的列式存储格式,并使用自动创建的聚集索引按时间顺序存储数据。列式存储格式提供了以下好处:

  • 降低了处理时间序列数据的复杂性
  • 提高了查询效率
  • 减少了磁盘使用
  • 减少了读取操作的I/O
  • WiredTiger缓存使用率提高

功能
时间序列集合的功能与普通集合类似。您可以像往常一样插入和查询数据。
MongoDB将时间序列集合视为由内部集合支持的可写非物化视图。插入数据时,内部集合会自动将时间序列数据组织为优化的存储格式。
当您查询时间序列集合时,您可以对每个度量值操作一个文档。对时间序列集合的查询利用了优化的内部存储格式,可以更快地返回结果。

重要

向后不兼容的功能

在降级之前,必须删除时序集合:

  • MongoDB 6.0或更高版本到MongoDB 5.0.7或更早版本。

  • MongoDB 5.3 到 MongoDB 5.0.5 或更早版本。

内部索引
当您创建时间序列集合时,MongoDB会自动在时间字段上创建一个内部聚集索引。内部索引提供了几个性能优势,包括提高了查询效率和减少了磁盘使用量。要了解有关聚集索引的性能优势的详细信息,请参阅聚集集合。
listIndexes不显示时间序列集合的内部索引。 

二、创建和查询时序集合

1、创建和查询时序集合

在将数据插入时间序列集合之前,必须使用db.createCollection()方法或create命令显式创建集合:

db.createCollection(
    "weather",
    {
       timeseries: {
          timeField: "timestamp",
          metaField: "metadata",
          granularity: "hours"
       }
    }
)

timeseries对象字段

创建时序集合时,请指定以下选项:

FieldTypeDescription
timeseries.timeField
字符串

必填。包含每个日期的字段的名称 时间序列文档。时序集合中的文档必须 具有有效的 BSON 日期作为 的值。timeField

timeseries.metaField
字符串

自选。包含每个元数据的字段的名称 时间序列文档。指定字段中的元数据应 是用于标记一系列唯一文档的数据。这 元数据应该很少(如果有的话)更改。

指定字段的名称可能与 这。该字段可以是任何类型。_idtimeseries.timeField

timeseries.granularity
字符串

自选。可能的值为:

  • "seconds"

  • "minutes"

  • "hours"

默认情况下,MongoDB 将 高频摄取。granularity"seconds"

手动设置参数以提高性能 通过优化时序集合中数据的存储方式 内部。要为 选择一个值,请选择 与连续传入之间的时间跨度最接近匹配 测量。granularitygranularity

如果指定 ,请考虑时间 具有相同连续传入测量之间的跨度 字段的唯一值。测量通常具有 字段的唯一值相同(如果来) 来自同一来源。timeseries.metaFieldmetaFieldmetaField

如果未指定 ,请考虑时间 在集合中插入的所有度量之间跨度。timeseries.metaField

expireAfterSeconds
自选。启用自动删除文档中的文档时序集合通过指定秒数 之后文件过期。MongoDB删除过期的文档 自然而然

时间序列选项允许的其他选项包括:

  • storageEngine

  • indexOptionDefaults

  • collation

  • writeConcern

  • comment

2、将测量值插入时间序列集合

您插入的每个文档都应包含一个度量值。要同时插入多个文档,请发出以下命令:

db.weather.insertMany( [
   {
      "metadata": { "sensorId": 5578, "type": "temperature" },
      "timestamp": ISODate("2021-05-18T00:00:00.000Z"),
      "temp": 12
   },
   {
      "metadata": { "sensorId": 5578, "type": "temperature" },
      "timestamp": ISODate("2021-05-18T04:00:00.000Z"),
      "temp": 11
   },
   {
      "metadata": { "sensorId": 5578, "type": "temperature" },
      "timestamp": ISODate("2021-05-18T08:00:00.000Z"),
      "temp": 11
   },
   {
      "metadata": { "sensorId": 5578, "type": "temperature" },
      "timestamp": ISODate("2021-05-18T12:00:00.000Z"),
      "temp": 12
   },
   {
      "metadata": { "sensorId": 5578, "type": "temperature" },
      "timestamp": ISODate("2021-05-18T16:00:00.000Z"),
      "temp": 16
   },
   {
      "metadata": { "sensorId": 5578, "type": "temperature" },
      "timestamp": ISODate("2021-05-18T20:00:00.000Z"),
      "temp": 15
   }, {
      "metadata": { "sensorId": 5578, "type": "temperature" },
      "timestamp": ISODate("2021-05-19T00:00:00.000Z"),
      "temp": 13
   },
   {
      "metadata": { "sensorId": 5578, "type": "temperature" },
      "timestamp": ISODate("2021-05-19T04:00:00.000Z"),
      "temp": 12
   },
   {
      "metadata": { "sensorId": 5578, "type": "temperature" },
      "timestamp": ISODate("2021-05-19T08:00:00.000Z"),
      "temp": 11
   },
   {
      "metadata": { "sensorId": 5578, "type": "temperature" },
      "timestamp": ISODate("2021-05-19T12:00:00.000Z"),
      "temp": 12
   },
   {
      "metadata": { "sensorId": 5578, "type": "temperature" },
      "timestamp": ISODate("2021-05-19T16:00:00.000Z"),
      "temp": 17
   },
   {
      "metadata": { "sensorId": 5578, "type": "temperature" },
      "timestamp": ISODate("2021-05-19T20:00:00.000Z"),
      "temp": 12
   }
] )

3、查询时间序列集合

您可以像查询标准MongoDB集合一样查询时间序列集合。
要从时间序列集合返回一个文档,请运行: 

db.weather.findOne({
   "timestamp": ISODate("2021-05-18T00:00:00.000Z")
})

输出:

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

 4对时间序列集合运行聚合


对于其他查询功能,请使用聚合管道,例如:

db.weather.aggregate( [
   {
      $project: {
         date: {
            $dateToParts: { date: "$timestamp" }
         },
         temp: 1
      }
   },
   {
      $group: {
         _id: {
            date: {
               year: "$date.year",
               month: "$date.month",
               day: "$date.day"
            }
         },
         avgTmp: { $avg: "$temp" }
      }
   }
] )

示例聚合管道按测量日期对所有文档进行分组,然后返回当天所有温度测量的平均值:

 {
  "_id" : {
    "date" : {
      "year" : 2021,
      "month" : 5,
      "day" : 18
    }
  },
  "avgTmp" : 12.714285714285714
}
{
  "_id" : {
    "date" : {
      "year" : 2021,
      "month" : 5,
      "day" : 19
    }
  },
  "avgTmp" : 13
}

二、List数据库中的时间序列集合

您可以输出数据库中的集合列表,并按各种属性(包括集合类型)筛选结果。您可以使用此功能列出数据库中的所有时间序列集合。

1、步骤

要列出数据库中的所有时间序列集合,请将listCollections命令与{type:“timeseries”}的筛选器一起使用:

db.runCommand( {
   listCollections: 1,
   filter: { type: "timeseries" }
} )

2、输出

对于时间序列集合,输出包括:

  • type: 'timeseries'

  • options: { timeseries: { ... } }

例如: 

{
  cursor: {
    id: Long("0"),
    ns: 'test.$cmd.listCollections',
    firstBatch: [
      {
        name: 'weather',
        type: 'timeseries',
        options: {
          timeseries: {
            timeField: 'timestamp',
            metaField: 'metadata',
            granularity: 'hours',
            bucketMaxSpanSeconds: 2592000
          }
        },
        info: { readOnly: false }
      }
    ]
  },
  ok: 1
}

 

📢文章下方有交流学习区!一起学习进步!也可以前往官网,加入官方微信交流群💪💪💪
📢首发CSDN博客,创作不易,如果觉得文章不错,可以点赞👍收藏📁评论📒
📢你的支持和鼓励是我创作的动力❗❗❗ 
 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值