PHP操作MongoDB时的整数问题及对策说明


Posted in PHP onMay 02, 2011

MongoDB本身有两种整数类型,分别是:32位整数和64位整数,但旧版的PHP驱动不管操作系统是32位还是64位,把所有整数都当做32位整数处理,结果导致64位整数被截断。为了在尽可能保持兼容性的前提下解决这个问题,新版PHP驱动加入了mongo.native-long选项,以期在64位操作系统中把整数都当做64位来处理,有兴趣的可参考:64-bit integers in MongoDB

那么PHP驱动真的完全解决了整数问题么?NO!在处理group操作的时候还有BUG

为了说明问题,我们先来生成一些测试数据:

<?php 
ini_set('mongo.native_long', 1); 
$instance = new Mongo(); 
$instance = $instance->selectCollection('test', 'test'); 
for ($i = 0; $i < 10; $i++) { 
$instance->insert(array( 
'group_id' => rand(1, 5), 
'count' => rand(1, 5), 
)); 
} 
?>

下面让我们使用group操作,根据group_id分组,汇总计算count:
<?php 
ini_set('mongo.native_long', 1); 
$instance = new Mongo(); 
$instance = $instance->selectCollection('test', 'test'); 
$keys = array('group_id' => 1); 
$initial = array('count' => 0); 
$reduce = ' 
function(obj, prev) { 
prev.count += obj.count; 
} 
'; 
$result = $instance->group($keys, $initial, $reduce); 
var_dump($result); 
?>

结果和预想的有出入,count没有实现累加,而是变成了[object Object],目前,如果必须使用group操作,那么有两种方法可以缓解这个问题:
ini_set('mongo.native_long', 0); 
$initial = array('count' => (float)0);

这两种方法都是治标不治本的权宜之计,既然当前PHP驱动里group的实现有问题,那我们就绕开它,用其它的方式实现同样的功能,这个方式就是MapReduce
<?php 
ini_set('mongo.native_long', 1); 
$instance = new Mongo(); 
$instance = $instance->selectDB('test'); 
$map = ' 
function() { 
emit(this.group_id, this.count); 
} 
'; 
$reduce = ' 
function(key, values) { 
var sum = 0; 
for (var index in values) { 
sum += values[index]; 
} 
return sum; 
} 
'; 
$result = $instance->command(array( 
'mapreduce' => 'test', 
'map' => $map, 
'reduce' => $reduce 
)); 
$result = iterator_to_array($instance->{$result['result']}->find()); 
var_dump($result); 
?>

把大象放冰箱里需要三步,而使用MapReduce仅仅需要Map和Reduce两步即可,这里有一个PDF文档生动的说明了MySQL中GROUP BY和MongoDB中MapReduce的对应关系:

PHP操作MongoDB时的整数问题及对策说明 

SQL to MongoDB

此外,还有很多资料可供参考,如:MongoDB Aggregation III: Map-Reduce Basics

说明:软件版本为MongoDB(1.6.5),PECL Mongo(1.1.4)。不同版本结论可能不同。

PHP 相关文章推荐
php GD绘制24小时柱状图
Jun 28 PHP
理解php Hash函数,增强密码安全
Feb 25 PHP
php常用字符串处理函数实例分析
Nov 22 PHP
php动态添加url查询参数的方法
Apr 14 PHP
php将图片文件转换成二进制输出的方法
Jun 10 PHP
PHP执行SQL文件并将SQL文件导入到数据库
Sep 17 PHP
PHP解压tar.gz格式文件的方法
Feb 14 PHP
PHP实现的折半查询算法示例
Oct 09 PHP
PHP 断点续传实例详解
Nov 11 PHP
thinkPHP5框架auth权限控制类与用法示例
Jun 12 PHP
PHP关于foreach复制知识点总结
Jan 28 PHP
Laravel5.5+ 使用API Resources快速输出自定义JSON方法详解
Apr 06 PHP
php HandlerSocket的使用
May 02 #PHP
深入理解PHP原理之错误抑制与内嵌HTML分析
May 02 #PHP
PHP错误抑制符(@)导致引用传参失败Bug的分析
May 02 #PHP
一些PHP Coding Tips(php小技巧)[2011/04/02最后更新]
May 02 #PHP
PHP中使用gettext来支持多语言的方法
May 02 #PHP
php中神奇的fastcgi_finish_request
May 02 #PHP
PHP开发不能违背的安全规则 过滤用户输入
May 01 #PHP
You might like
欧美媒体选出10年前最流行的17部动画
2017/01/18 日漫
PHP strtok()函数的优点分析
2010/03/02 PHP
php遍历解析xml字符串的方法
2016/05/05 PHP
Yii CFileCache 获取不到值的原因分析
2017/02/08 PHP
关于PHP定时发送服务的解决办法
2017/04/23 PHP
分享10篇优秀的jQuery幻灯片制作教程及应用案例
2011/04/16 Javascript
Jquery下:nth-child(an+b)的使用注意
2011/05/28 Javascript
利用JS实现浏览器的title闪烁
2013/07/08 Javascript
JQUERY 获取IFrame中对象及获取其父窗口中对象示例
2013/08/19 Javascript
使用jQuery设置disabled属性与移除disabled属性
2014/08/21 Javascript
使用JQ来编写最基本的淡入淡出效果附演示动画
2014/10/31 Javascript
Javascript 拖拽的一些高级的应用(逐行分析代码,让你轻松了拖拽的原理)
2015/01/23 Javascript
javascript实现unicode与ASCII相互转换的方法
2015/12/10 Javascript
Bootstrap树形组件jqTree的简单封装
2016/01/25 Javascript
JS检测页面中哪个HTML标签触发点击事件的方法
2016/06/17 Javascript
js实现浏览器倒计时跳转页面效果
2016/08/12 Javascript
JS实现仿饿了么在浏览器标签页失去焦点时网页Title改变
2017/06/01 Javascript
JS手机端touch事件计算滑动距离的方法示例
2017/10/26 Javascript
Vue使用vue-area-linkage实现地址三级联动效果的示例
2018/06/27 Javascript
详解处理bootstrap4不支持远程静态框问题
2018/07/20 Javascript
微信小程序实现炫酷的弹出式菜单特效
2019/01/28 Javascript
vue通过数据过滤实现表格合并
2020/11/30 Javascript
Node.js HTTP服务器中的文件、图片上传的方法
2019/09/23 Javascript
javascript使用Blob对象实现的下载文件操作示例
2020/04/18 Javascript
echarts实现获取datazoom的起始值(包括x轴和y轴)
2020/07/20 Javascript
Python设计模式之代理模式实例
2014/04/26 Python
python 捕获shell脚本的输出结果实例
2017/01/04 Python
使用html2canvas.js实现页面截图并显示或上传的示例代码
2018/12/18 HTML / CSS
《七颗钻石》教学反思
2014/02/28 职场文书
个人评语大全
2014/05/04 职场文书
酒店爱岗敬业演讲稿
2014/09/02 职场文书
师德师风自我评价范文
2014/09/11 职场文书
领导班子个人查摆问题对照检查材料
2014/10/02 职场文书
工作收入住址证明
2014/10/28 职场文书
教师岗位职责
2015/02/03 职场文书
2016年小学推普宣传周活动总结
2016/04/06 职场文书