解析:使用php mongodb扩展时 需要注意的事项
程序员文章站
2022-07-11 09:16:05
最近在使用php的mongo 扩展进行数据统计计算,其中有一个时间戳字段,由于精确到了毫秒,长度有13位,但由于开始的时候是以字符串的形式存储:复制代码 代码如下:{ "_...
最近在使用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客户端直接查询是有结果的:
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) );
复制代码 代码如下:
{ "_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客户端直接查询是有结果的:
复制代码 代码如下:
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) );
下一篇: Python字符转换
推荐阅读
-
解析PHP中$_FILES的使用以及注意事项
-
解析:使用php mongodb扩展时 需要注意的事项
-
ThinkPHP后台首页index使用frameset时的注意事项分析_PHP
-
ThinkPHP后台首页index使用frameset时的注意事项分析_php实例
-
使用php mongodb扩展时比较需要注意的事项_PHP教程
-
解析PHP中$_FILES的使用以及注意事项
-
ThinkPHP后台首页index使用frameset时的注意事项分析_PHP
-
使用php mongodb扩展时比较需要注意的事项_PHP教程
-
使用WebApi时需要注意的事项:
-
DLL中使用FindResource时需要注意的事项