最近在使用php的mongo 扩展进行数据统计计算,其中有一个时间戳字段,由于精确到了毫秒,长度有13位,但由于开始的时候是以字符串的形式存储:
实例代码如下:
{ _id : objectid(504eea97e4b023cf38e34039), in_ts : numberlong(1347349143699), log : { guid : 4d1f3079-7507-f4b0-e7af-5432d5d8229d, p : view_prop_yeppage_zheng, cid : 11, url : http://shanghai.haozu.com/rental/broker/n/10481780, rfpn : listing_v2_indexpage_all, site : haozu, agent : mozilla/4.0 (compatible; msie 6.0; windows nt 5.1; sv1), stamp : 1347349162159, cip : 116.226.70.44, referer : http://shanghai.haozu.com/shop/1464934/, cstamp : 1347349323125, sessid : fa798056-f9e7-f961-41e0-cc95c850fa47, uguid : c00ff55b-3d3d-4b31-4318-12345b0dbe64, pn : view_prop_yeppage_zheng, cstparam : { proid : numberlong(10481780), brokerid : 326792, tradetype : 2, usertype : 0, channel : site, entry : 1, commid : 1666 } }, out_ts : numberlong(1347349466083), rule : 0, status : ok, txid : 0 }
后来改成数字格式:
实例代码如下:
{ _id : objectid(504eea97e4b023cf38e34039), in_ts : numberlong(1347349143699), log : { guid : 4d1f3079-7507-f4b0-e7af-5432d5d8229d, p : view_prop_yeppage_zheng, cid : 11, url : http://shanghai.haozu.com/rental/broker/n/10481780, rfpn : listing_v2_indexpage_all, site : haozu, agent : mozilla/4.0 (compatible; msie 6.0; windows nt 5.1; sv1), stamp : numberlong(1347349162159), cip : 116.226.70.44, referer : http://shanghai.haozu.com/shop/1464934/, cstamp : 1347349323125, sessid : fa798056-f9e7-f961-41e0-cc95c850fa47, uguid : c00ff55b-3d3d-4b31-4318-12345b0dbe64, pn : view_prop_yeppage_zheng, cstparam : { proid : numberlong(10481780), brokerid : 326792, tradetype : 2, usertype : 0, channel : site, entry : 1, commid : 1666 } }, out_ts : numberlong(1347349466083), rule : 0, status : ok, txid : 0 }为字符串时,使用下面的查询是正常的 $query = array ('log.stamp' => array ('$gte' => '1347346800000', '$lt' => '1347350400000'));
但是改为数字后,使用下面的查询,死活没有结果,但是直接在mongo客户端直接查询是有结果的:
实例代码如下:
{ _id : objectid(504eea97e4b023cf38e34039), in_ts : numberlong(1347349143699), log : { guid : 4d1f3079-7507-f4b0-e7af-5432d5d8229d, p : view_prop_yeppage_zheng, cid : 11, url : http://shanghai.haozu.com/rental/broker/n/10481780, rfpn : listing_v2_indexpage_all, site : haozu, agent : mozilla/4.0 (compatible; msie 6.0; windows nt 5.1; sv1), stamp : numberlong(1347349162159), cip : 116.226.70.44, referer : http://shanghai.haozu.com/shop/1464934/, cstamp : 1347349323125, sessid : fa798056-f9e7-f961-41e0-cc95c850fa47, uguid : c00ff55b-3d3d-4b31-4318-12345b0dbe64, pn : view_prop_yeppage_zheng, cstparam : { proid : numberlong(10481780), brokerid : 326792, tradetype : 2, usertype : 0, channel : site, entry : 1, commid : 1666 } }, out_ts : numberlong(1347349466083), rule : 0, status : ok, txid : 0 }为字符串时,使用下面的查询是正常的 $query = array ('log.stamp' => array ('$gte' => '1347346800000', '$lt' => '1347350400000'));
实例代码如下:
db.haozu_success.find({'log.stamp':{$gte:1347346800000,$lt:1347350400000}})
php手册上也是这么个用法:
$query = array ('log.stamp' => array ('$gte' => 1347346800000, '$lt' => 1347350400000));
花了好大一会找原因,开始时怀疑是php扩展的bug导致,经过一番思考.突然想到可能是类型问题导致,发现手册上有types 介绍,所以正确的用法如下:
实例代码如下:
$query = array ('log.stamp' => array ('$gte' => new mongoint64($time_range['start']), '$lt' => new mongoint64($time_range['end'])));
另外,在使用mapreduce进行数据统计时,为了防止cursor出现超时异常,还需要设置一下超时时间
实例代码如下:
$map = new mongocode ( ' function(){ var prop_id=this.log.cstparam.proid; var key=this.log.site+prop_id emit(key,{channel:this.log.site,prop_id:prop_id,count:1}); } ' ); $reduce = new mongocode ( ' function(key,emits){ var total=0; for(var i in emits){ total+=emits[i].count; } return {channel:emits[0].channel,prop_id:eval(emits[0].prop_id),count:total}; } ' ); $this->mongo_db->command ( array ('mapreduce' => $collection_name, 'map' => $map, 'reduce' => $reduce, 'out' => $tmp_result, 'query' => $query),array('timeout'=>self::mongo_cursor_timeout) );
