Docs 菜单
Docs 主页
/
MongoDB Manual
/

创建和查询时间序列集合

在此页面上

  • 创建时间序列集合
  • 在时间序列集合中插入测量值
  • 查询时间序列集合
  • 在时间序列集合上运行聚合

本页将介绍如何创建和查询时间序列集合,并附有代码示例。

重要

功能兼容性版本要求

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

1

使用 db.createCollection() 方法或 create 命令创建集合。例如:

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

timeField 设置为包含时间数据的字段,将 metaField 设置为包含元数据的字段:

timeseries: {
timeField: "timestamp",
metaField: "metadata"
}

重要

有关 metaField 行为和选择的更多信息,请参阅 metaFields。

3

使用以下两种方法来定义每个数据桶的时间间隔。有关详细信息,请参阅设置时间序列数据的粒度

重要

更改时间序列粒度

创建后,您可以使用 collMod 方法修改粒度或桶的定义。但是,您只能增加每个数据桶所涵盖的时间跨度,而无法减少它。

  1. 定义一个 granularity 字段:

    timeseries: {
    timeField: "timestamp",
    metaField: "metadata",
    granularity: "seconds"
    }

  1. 在 MongoDB 6.3 及更高版本中,您可以定义 bucketMaxSpanSecondsbucketRoundingSeconds 字段。两个值必须相同:

    timeseries: {
    timeField: "timestamp",
    metaField: "metadata",
    bucketMaxSpanSeconds: "300",
    bucketRoundingSeconds: "300"
    }
4

(可选)设置 expireAfterSeconds,使文档在 timeField 的值达到该值时及之后均过期:

timeseries: {
timeField: "timestamp",
metaField: "metadata",
granularity: "seconds"
},
expireAfterSeconds: 86400

时间序列集合包含以下字段:

字段
类型
说明
timeseries.timeField
字符串

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

timeseries.metaField
字符串

可选。包含每个时间序列文档中元数据的字段的名称。指定字段中的元数据应是用于标记一系列独一无二的文档的数据。元数据应该很少改变(如有)。指定字段的名称可能不是 timeseries.timeField 或与 _id 相同。该字段可以是任何数据类型。

虽然metaField字段是可选的,但使用元数据可以改进查询优化。 例如,MongoDB 会自动为新集合的metaFieldtimeField字段创建复合索引。 如果您没有为此字段提供值,则仅根据时间对数据进行分桶。

timeseries.granularity
整型

可选。如果设置 bucketRoundingSecondsbucketMaxSpanSeconds,请勿使用。

可能的值为 seconds(默认)、minutes、和 hours

granularity 设置为最接近连续输入时间戳之间时间的值。这可通过优化 MongoDB 在集合中存储数据的方式来提高性能。

有关粒度和桶间隔的更多信息,请参阅设置时间序列数据的粒度。

timeseries.bucketMaxSpanSeconds
整型

可选。与 bucketRoundingSeconds 结合使用以作为 granularity 的替代方案。设置同一存储桶中不同时间戳之间的最大时间间隔。

可能的值为 1-31536000。

6.3 版本中的新功能

timeseries.bucketRoundingSeconds
整型

可选。与 bucketMaxSpanSeconds 结合使用作为 granularity 的替代方案。必须等于 bucketMaxSpanSeconds

当文档需要新的存储桶时,MongoDB 会按此间隔对文档时间戳的值向下取整,以设置存储桶的最小开始时间。

6.3 版本中的新功能

expireAfterSeconds
整型
可选。通过指定文档过期后的秒数,启用自动删除时间序列集合中文档的功能。MongoDB 自动删除过期文档。请参阅设置自动删除时间序列集合 (TTL),获取更多信息。

其他不特定于时间序列集合的允许选项:

  • storageEngine

  • indexOptionDefaults

  • collation

  • writeConcern

  • comment

提示

请参阅:

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

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() 方法。

提示

优化插入性能

要了解如何优化大型操作的插入,请参阅优化插入

查询时间序列集合的方式与查询标准 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")
}

有关时间序列查询的更多信息,请参阅优化查询性能

要获得其他查询功能,请使用聚合管道,例如:

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
}

后退

时间序列