MongoDB 5.0 发布的新功能,仅在 5.0 之後的版本提供。
时间序列集合(Time series collection) 是一个新型态的集合,有别於 capped collection
与 一般 Collection
,它有诸多限制:
drop collection
capped
或 一般
collection,反之亦然unique
(_id为例外), partial
metaField
, timeField
(後面说明)两栏位仅有在建立 Collection 才可以决定,之後无法修改。看了这麽多限制後,还是不知道什麽是时间序列集合。基本上该功能就可以想像成依照时间来进行统计分析的集合,像是股票资料或天气资料这种,依照时间进行,然後去统计分析股票价位高低或者温度的高低。
timeField
时间栏位,指定要做为统计的时间栏位,必须是要时间的资料型别
metaField
分群的栏位,统计资料会自动以该栏位进行分群。
因为只能指定一个栏位,所以可以进行变通,例如原本是 { "name": "Bruce"}
改为 { "name": "Bruce", "lastName": "Lee" }
granularity
统计时间粒度,可以是 seconds
, minutes
或 hours
有着前面的知识後我们来准备一个范例,建立语法以及预设资料如下
db.createCollection("order.ts", {
timeseries: {
timeField: "orderDate",
metaField: "customerName",
granularity: "hours"
},
expireAfterSeconds: 3600*31*6
});
资料范本
{
"customerId": 10001,
"customerName": { "name":"Bruce", "lastName": "Lee" },
"orderPrize": 1280,
"orderStatus": 1,
"orderDate": ISODate("2021-09-01T11:00:00.000Z"),
"deliverDate": ISODate("2021-09-05T15:00:00.000Z")
},
{
"customerId": 10001,
"customerName": { "name":"Bruce", "lastName": "Lee" },
"orderPrize": 1880,
"orderStatus": 3,
"orderDate": ISODate("2021-09-01T12:00:00.000Z"),
"deliverDate": ISODate("2021-09-06T16:00:00.000Z")
},
{
"customerId": 10001,
"customerName": { "name":"Bruce", "lastName": "Lee" },
"orderPrize": 540,
"orderStatus": 2,
"orderDate": ISODate("2021-09-02T03:00:00.000Z"),
"deliverDate": ISODate("2021-09-07T17:00:00.000Z")
},
{
"customerId": 10002,
"customerName": { "name":"Old", "lastName": "Chou" },
"orderPrize": 2300,
"orderStatus": 1,
"orderDate": ISODate("2021-09-01T10:00:00.000Z"),
"deliverDate": ISODate("2021-09-07T14:00:00.000Z")
},
{
"customerId": 10003,
"customerName": "Kate",
"orderPrize": 2890,
"orderStatus": 3,
"orderDate": ISODate("2021-09-01T12:00:00.000Z"),
"deliverDate": ISODate("2021-09-07T14:00:00.000Z")
}
timeseries> show collections
order.ts [time-series]
system.buckets.order.ts
system.views
建立完後我们看到除了原本的 order.ts
collection 有被标注为 [time-series]
,还多了两个:
system.views
{
"_id" : "timeseries.order.ts",
"viewOn" : "system.buckets.order.ts",
"pipeline" : [
{
"$_internalUnpackBucket" : {
"timeField" : "orderDate",
"metaField" : "customerName",
"bucketMaxSpanSeconds" : 2592000,
"exclude" : []
}
}
]
}
里面存放了 bukets 的 view,与建立的资讯
system.buckets.order.ts
这里总共有四笔资料,分别是按照 metaField
作为 group
统计而来的,碍於篇幅,我举其中一个例子并分段来看
Part 1
{
"_id" : ObjectId("612ec2808b826f0fc8ce4afa"),
"control" : {
"version" : 1,
"min" : {
"_id" : ObjectId("614eee10ebdbba2a6c81adbd"),
"customerId" : 10001.0,
"orderPrize" : 540.0,
"orderStatus" : 1.0,
"orderDate" : ISODate("2021-09-01T00:00:00.000Z"),
"deliverDate" : ISODate("2021-09-05T15:00:00.000Z")
},
"max" : {
"_id" : ObjectId("614eee10ebdbba2a6c81adbf"),
"customerId" : 10001.0,
"orderPrize" : 1880.0,
"orderStatus" : 3.0,
"orderDate" : ISODate("2021-09-02T03:00:00.000Z"),
"deliverDate" : ISODate("2021-09-07T17:00:00.000Z")
}
},
这边直接帮你算出 metaField { "name":"Bruce", "lastName": "Lee" }
分类里的每个项目的最小值与最大值,要是能设定多算一些统计值也是不错吧。
有个小疑问是最小值的 orderDate 值是 ISODate("2021-09-01T00:00:00.000Z")
但原始数据明明是 ISODate("2021-09-01T10:00:00.000Z")
,可能会是个 bug?
Part 2
"meta" : {
"lastName" : "Lee",
"name" : "Bruce"
},
就是刚开始建立 Collection 时指定用来分群的 metaField
Part3
"data" : {
"orderDate" : {
"0" : ISODate("2021-09-01T11:00:00.000Z"),
"1" : ISODate("2021-09-01T12:00:00.000Z"),
"2" : ISODate("2021-09-02T03:00:00.000Z")
},
"customerId" : {
"0" : 10001.0,
"1" : 10001.0,
"2" : 10001.0
},
"deliverDate" : {
"0" : ISODate("2021-09-05T15:00:00.000Z"),
"1" : ISODate("2021-09-06T16:00:00.000Z"),
"2" : ISODate("2021-09-07T17:00:00.000Z")
},
"orderPrize" : {
"0" : 1280.0,
"1" : 1880.0,
"2" : 540.0
},
"_id" : {
"0" : ObjectId("614eee10ebdbba2a6c81adbd"),
"1" : ObjectId("614eee10ebdbba2a6c81adbe"),
"2" : ObjectId("614eee10ebdbba2a6c81adbf")
},
"orderStatus" : {
"0" : 1.0,
"1" : 3.0,
"2" : 2.0
}
}
从这边可以看到 data
这个项目里面存放的就是各个栏位的原始数据,如果要做聚合、统计都能够从这边直接取用,顺序也是按照写入的顺序。
看到这边我就不再继续延伸使用 aggregation
示范内容了,基本上 time series collection
就是帮你把资料按照另一个格式进行储存,让你可以更快的在感兴趣的栏位进行统计。
另外因为是 demo 概念,没有建立 index,请务必在使用时加上相对应得索引,使你的查询更加有效率。
例如帮你自动分桶的集合 system.buckets.order.ts
能这样做,或者是原本的 order.ts
集合。
本系列文章会同步发表於我个人的部落格 Pie Note
身为开发时程紧凑的工程师 遇到问题或是疑惑时必须要能快速的排除 通常在专案中遇到不熟悉的物件,想到 ...
Mac 启动磁碟满了怎麽办?当你耗尽了磁碟的储存空间後,你将无法存取资料档案。不少 Mac 用户都曾...
哇~~~终於完成三十天的文章了,这里面记录了满满我对於这个专案学习的过程,以及在最後展现出成果实在是...
在辅导企业高层主管上课时候,我常跟他们说如果不了解你的产品市场那麽就无法开始执行方案,因此在这个後疫...
前言 retrofit负责请求网路资料请求,rxjava负责异步执行、thread之间的切换,今天实...