MongoDB分組方式
我們用慣了MySQL等關係型數據庫的group,一開始用MongoDB的聚合統計有點麻煩,所以在這裏做一個本人的使用記錄。
分組方式:
- group
- 特徵
group缺點多多,我理解它是mapreduce的低配版,如返回結果集不能超過16M, group操作不會處理超過10000個唯一鍵,不支持分片,好像還不能利用索引。
用法:有以下6個參數
1.key:用來分組文檔的字段。和keyf兩者必須有一個
2.keyf:可以接受一個javascript函數。用來動態的確定分組文檔的字段。和key兩者必須有一個
3.initial:reduce中使用變量的初始化
4.$reduce:執行的reduce函數。
5.condition:執行過濾的條件。
6.finallize:在reduce執行完成,結果集返回之前對結果集最終執行的函數。可選的。
- 實例:
collection字段:PACKAGE_CREATED(時間戳),ROUTER_STATUS,ROUTER_CREATED
db.test.group(
{
key:{ROUTER_STATUS:true},
initial:{num:0},
$reduce:function(doc,prev){
prev.num++
},
condition:{ROUTER_STATUS:{$ne:2}},
});
- aggregate
db.test.aggregate(
[
{
$project: {
PACKAGE_CREATED:1,
yearMonthDay: { $dateToString: { format: "%Y/%m/%d", date: {"$add":[new Date(0),{$multiply:["$PACKAGE_CREATED",1000]},28800000] } }},
time:new Date(0)
},
$match: {
yearMonthDay: '2019/12/26'
}
}
]
)
關鍵點在於{"$add":[new Date(0),{$multiply:["$PACKAGE_CREATED",1000]},28800000] };
即格林威治開始時間(1970-01-01 00:00:00)+ 存儲時間戳 + 時差。
注意:1)MongoDB時間基本單位是ms,所以乘以1000;
2)我的MongoDB是UTC時區,即中時區(0度經線)而中國是東八區,所以加8h
- PHP中使用
需要安裝MongoDB擴展
<?php
namespace Test;
use MongoDB\BSON\UTCDateTime;
class Test(){
public function test()
{
$utcdatetime = new UTCDateTime(0);//1970.01.01 00:00:00
$repair_time = 3600000 * 8;//修復時差
$pipeline[] = [
'$match' => ['PACKAGE_CREATED' => ['$gte'=>$start_time,'$lte' => $end_time]]
];
$pipeline[] = [
'$project' => [
'datetime' => ['$dateToString' => [ 'format' => "%Y/%m/%d", 'date' => ['$add' => [$utcdatetime,['$multiply' => ['$ROUTER_DELIVERED',1000]],$repair_time]]]]
]
];
$pipeline[] = [
'$group' => ['_id' => ['router_delivered' => '$datetime'], 'count' => ['$sum' => 1]]
];
$pipeline[] = [
'$project' => ['_id' => 0,'router_delivered' => '$_id.router_delivered','count' => '$count']
];
$pipeline[] = [
'$sort' => ['router_delivered' => 1]
];
//要求返回數組結果,而不是BSON對象
$options = [
'typeMap' => [
'root' => 'array',
'document' => 'array',
'array' => 'array'
]
];
$data = $this->db->aggregate($pipeline,$options)->toArray();
var_dump($data);
}
}
關鍵是要使用MongoDB擴展的MongoDB\BSON\UTCDateTime類,new一個它的實例,作爲格林威治開始時間