Docs 菜单
Docs 主页
/
MongoDB Manual

时间序列集合

在此页面上

  • 时间序列集合
  • 步骤
  • 行为

版本 5.0 中的新增功能

时间序列集合可有效存储一段时间内的测量序列。 时间序列数据是随时间推移收集的任何数据,由一个或多个不变参数唯一标识。 标识时间序列数据的不变参数通常是数据源的元数据。

例子
测量
Metadata

天气数据

温度

传感器标识符、位置

stockdata

股票价格

证券报价机、交易所

网站访客

查看计数

URL

版本 5.0 中的新增功能

时间序列集合可提供储时间序列数据的效率。在时间序列集合中,写入操作的组织方式保证同源数据与来自相似时间点的其他数据点一起存储。

与普通集合相比,在时间序列集合中存储时间序列数据可提高查询效率,减少时间序列数据和二级索引的磁盘使用量。

注意

您只能在featureCompatibilityVersion设置为5.0的系统上创建时间序列集合。

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

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

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

字段
类型
说明

timeseries.timeField

字符串

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

timeseries.metaField

字符串

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

指定字段的名称不能是 _id,也不能与 timeseries.timeField 相同。字段可以是任何类型。

timeseries.granularity

字符串

可选。 可能的值为"seconds""minutes""hours" 。 默认情况下,MongoDB 将granularity设置为"seconds" ,以进行高频摄取。

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

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

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

expireAfterSeconds

数字

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

允许与timeseries选项一起使用的其他选项包括:

  • storageEngine

  • indexOptionDefaults

  • collation

  • writeConcern

  • comment

提示

请参阅:

警告

请勿尝试创建名称为system.profile的时间序列集合或视图,否则 MongoDB Server 会崩溃。

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

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

要从时间序列集合中检索一份文档,请发出以下命令:

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

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

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
}

要确定集合是否为时间序列类型,请使用 listCollections 命令:

db.runCommand( { listCollections: 1.0 } )

如果集合是时间序列集合,则返回:

{
cursor: {
id: <number>,
ns: 'test.$cmd.listCollections',
firstBatch: [
{
name: <string>,
type: 'timeseries',
options: {
expireAfterSeconds: <number>,
timeseries: { ... }
},
...
},
...
]
}
}

时间序列集合的行为与普通集合相同。 您可以像平常一样插入和查询数据。 MongoDB 将时间序列集合视为内部集合的可写非物化视图,在插入时自动将时间序列数据组织成优化的存储格式。

查询时间序列集合时,每次测量都会对一个文档进行操作。 对时间序列集合的查询利用优化的内部存储格式,更快地返回结果。

提示

为了提高查询性能,您可以在指定为 metaFieldtimeField 的字段上手动添加二级索引

时间序列集合按时间自动对数据进行排序和索引。 listIndexes不显示时间序列集合的内部索引。

如果在1970-01-01T00:00:00.000Z之前或2038-01-19T03:14:07.000Z之后将文档插入到具有timeField值的集合中,MongoDB 会记录警告并阻止某些查询优化使用内部索引。 在timeField创建二级索引,以恢复查询性能并解决日志警告问题。

时间序列集合会忽略全局默认压缩算法snappy ,而使用zstd ,除非在创建集合时使用storageEngine选项指定了不同的压缩算法。 例如,要将新weather集合的压缩算法更改为snappy ,请添加以下选项:

db.createCollection(
"weather",
{
timeseries: {
timeField: "timestamp"
},
storageEngine: {
wiredTiger: {
configString: "block_compressor=snappy"
}
}
}
)

有效的 block_compressor 选项包括:

  • snappy

  • zlib

  • zstd (默认)

  • none

后退

固定大小集合