技术干货 | MongoDB 如何创建并查询时间序列集合?
上一篇重点介绍了时间序列数据和 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 | 可选。取值包括:
默认情况下,MongoDB将高频数据采集的 granularity 设置为“秒(seconds)”。 |
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中文社区