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执行速度全攻略
Oct 09 PHP
一个改进的UBB类
Oct 09 PHP
php中的登陆login
Jan 18 PHP
Windows下IIS6/Apache2.2.4+MySQL5.2+PHP5.2.1安装配置方法
May 03 PHP
php用数组返回无限分类的列表数据的代码
Aug 08 PHP
php foreach 参数强制类型转换的问题
Dec 10 PHP
php实现文件编码批量转换
Mar 10 PHP
thinkphp常见路径用法分析
Dec 02 PHP
php对关联数组循环遍历的实现方法
Mar 13 PHP
PHP根据session与cookie用户登录状态操作类的代码
May 13 PHP
实例介绍PHP删除数组中的重复元素
Mar 03 PHP
PHP接口类(interface)的定义、特点和应用示例
May 18 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
PHP正确解析UTF-8字符串技巧应用
2012/11/07 PHP
PHP实现的简单适配器模式示例
2017/06/22 PHP
JS 自动安装exe程序
2008/11/30 Javascript
比较详细的关于javascript 解析json的代码
2009/12/16 Javascript
javascript中字符串拼接需注意的问题
2010/07/13 Javascript
JavaScript实现QueryString获取GET参数的方法
2013/07/02 Javascript
jQuery中empty()方法用法实例
2015/01/16 Javascript
javascript中关于&amp;&amp; 和 || 表达式的小技巧分享
2015/04/10 Javascript
jQuery蓝色风格滑动导航栏代码分享
2015/08/19 Javascript
jquery+html5时钟特效代码分享(可设置闹钟并且语音提醒)
2020/03/30 Javascript
jquery Deferred 快速解决异步回调的问题
2016/04/05 Javascript
JavaScript实现阿拉伯数字和中文数字互相转换
2016/06/12 Javascript
浅析JavaScript中命名空间namespace模式
2016/06/22 Javascript
bootstrap table复杂操作代码
2016/11/01 Javascript
微信JS-SDK自定义分享功能实例详解【分享给朋友/分享到朋友圈】
2016/11/25 Javascript
javascript事件的绑定基础实例讲解(34)
2017/02/14 Javascript
nodejs中使用HTTP分块响应和定时器示例代码
2017/03/19 NodeJs
js每隔两秒输出数组中的一项(实例)
2017/05/28 Javascript
js 只比较时间大小的实例
2017/10/26 Javascript
解决在Bootstrap模糊框中使用WebUploader的问题
2018/03/22 Javascript
浅谈开发eslint规则
2018/10/01 Javascript
jQuery选择器之基本选择器用法实例分析
2019/02/19 jQuery
JS实现图片幻灯片效果代码实例
2020/05/21 Javascript
Vue Element校验validate的实例
2020/09/21 Javascript
JavaScript实现切换多张图片
2021/01/27 Javascript
[01:05]主宰至宝剑心之遗
2017/03/16 DOTA
Django框架中方法的访问和查找
2015/07/15 Python
Python实现将数据框数据写入mongodb及mysql数据库的方法
2018/04/02 Python
详解python的argpare和click模块小结
2019/03/31 Python
如何基于Python批量下载音乐
2019/11/11 Python
Python3.7下安装pyqt5的方法步骤(图文)
2020/05/12 Python
Sneaker Studio法国:购买运动鞋
2018/06/08 全球购物
建筑投标担保书
2014/05/20 职场文书
新闻学专业求职信
2014/07/28 职场文书
员工年度工作总结2015
2015/05/18 职场文书
vue2实现provide inject传递响应式
2021/05/21 Vue.js