技术干货 | MongoDB 如何创建并查询时间序列集合?

随风康康
发布于 2023-5-22 16:26
浏览
0收藏

上一篇重点介绍了时间序列数据和 MongoDB 时间序列集合功能的基本情况,本篇则将着重通过示例代码展示如何创建和查询时间序列集合

创建时间序列集合

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

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

📒 重要:

功能兼容版本

只能在 featureCompatibilityVersion 设置为 5.0 或更高版本的系统上创建时间序列集合。

​timeseries​​对象字段

在创建时间序列集合时,指定以下选项:





字段







类型







描述







timeseries.timeField





string






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







timeseries.metaField





string






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


指定字段的名称不能为 _id 或与 timeseries.timeField 相同。元数据的字段可以是任何类型。







timeseries.granularity





string






可选。取值包括:


  • "seconds"

  • ​​"minutes"

  • "hours"

默认情况下,MongoDB将高频数据采集的 granularity 设置为“秒(seconds)”

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

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

如果没有指定 timeseries.metaField 字段,则考虑插入集合中的所有测量值之间的时间跨度。







expireAfterSeconds







number







可选。通过指定文档过期秒数来启用时间序列集合(time series collection)中的文档自动删除功能。MongoDB 会自动删除过期文档。有关更多信息,请参阅设置时间序列集合自动删除(TTL)​。



timeseries 中允许的其他选项还有:

  • ​storageEngine​
  • ​​​indexOptionDefaults​
  • ​collation​
  • ​writeConcern​
  • ​comment​

📒 提示:

参考 db.createCollection() 和 create

在时间序列集合中插入测量值

插入的每个文档都应该包含一个测量值。要同时插入多个文档,使用以下命令:

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

要插入单个文档,使用 db.collection.insertOne() 方法。

📒 提示:

优化插入性能

要了解如何为大型操作优化插入,请参阅优化插入(Optimize Inserts)

查询时间序列集合

可以按照查询标准 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")
}

在时间序列集合上进行聚合运算

对于额外的查询功能,可以使用聚合管道(aggregation pipeline),例如:

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
}


原文:Create and Query a Time Series Collection

关于译者:

张清荣,MongoDB 中文社区成员,现就职于中国联通软件研究院。



文章转载自公众号: Mongoing中文社区

分类
标签
已于2023-5-22 16:26:54修改
收藏
回复
举报
回复
    相关推荐