最近接到一个需求需要统计我们公司各个终端的版本号使用情况并且提供一个后台,并且每天中午12点清除。
后台页面如下:
当时拿到需求有两种做法处理这个问题:
1.放mysql再写一个定时脚本每天12点清空数据
2.放mongodb使用expireAfterSeconds索引每天12点定时清空
第一种方案有个缺点是还要维护一个脚本,索引我选择第二种方案
创建expireAfterSeconds索引
db.netbar_version.createIndex( { "expire_time": 1 }, { expireAfterSeconds: 0 } )
expireAfterSeconds如果设置为0 过期时间由expire_time时间来决定过期
如果不设置为0 过期时间由expire_time的时间加上expireAfterSeconds来决定
mongodb的expireAfterSeconds的指定的索引时间是ISODate时间类型格式
再比较老的版本创建mongodb的isodate对象的方法为MongoDate 在现在官网已经提示该方法被废弃了,由UTCDateTime来取代
插入一条次日12点清空的数据
$time = mktime(12,0,0,date('m'),date('d') + 1,date('Y'));
$expireTime = new UTCDateTime($time * 1000);// UTCDateTime使用的参数是微妙 mktime生成参数的为秒 需要乘1000
$model = new NetbarVersion();
$model->insert([
'expire_time' => $expireTime,
'...' => ...,
......
.....
]);
然后插入成功后我们在mongodb可以看到
> db.netbar_version.find().pretty();
{
"_id" : ObjectId("5978169a6cc7fd4100257b11"),
"netbar_id" : "432",
"netbar_name" : "60cn天网吧",
"coobar_server" : "6000",
"coobar_jxc" : "",
"coobar_client" : "6000",
"coobar_console" : "",
"coobar_voice" : "",
"coobar_db" : "",
"create_time" : 1501042330,
"expire_time" : ISODate("2017-07-27T04:00:00Z"),
"update_time" : 1501042330,
"netbar_number" : "200381"
}
{
"_id" : ObjectId("597805126cc7fd359f24c251"),
"netbar_id" : "34",
"netbar_name" : "李工01",
"coobar_server" : "6000",
"coobar_jxc" : "",
"coobar_client" : "",
"coobar_console" : "",
"coobar_voice" : "",
"coobar_db" : "",
"create_time" : 1501037842,
"expire_time" : ISODate("2017-07-27T04:00:00Z"),
"update_time" : 1501037842,
"netbar_number" : "200009"
}
注意:我们插入的过期时间为2017年7月27的12:00 但是转换乘iso时间会少8个小时(GTM-8时区和ISO时区误差8个小时), 最终还是会根据我们实际插入的时间(2017年7月27的12:00)进行扫描判断数据是否需要删除
如果在tp5发现mongodb插入对象的时候发生异常,请更新下tp5的mongodb的拓展,或者手动在mongodb拓展的Builder文件下找到parseData代码改成如下
protected function parseData($data, $options)
{
if (empty($data)) {
return [];
}
$result = [];
foreach ($data as $key => $val) {
$item = $this->parseKey($key);
if (is_array($val) && isset($val[0]) && 'exp' == $val[0]) {
$result[$item] = $val[1];
} elseif (is_null($val)) {
$result[$item] = 'NULL';
} else {
$result[$item] = $this->parseValue($val, $key);
}
}
return $result;
}
数据既然插入进去了,后台就是简单的查找和group转成相对应的图表数据