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 相关文章推荐
新浪微博API开发简介之用户授权(PHP基础篇)
Sep 25 PHP
php数字转汉字代码(算法)
Oct 08 PHP
PHP判断远程图片或文件是否存在的实现代码
Feb 20 PHP
phpnow php探针环境检测代码
Nov 04 PHP
php合并数组中相同元素的方法
Nov 13 PHP
php利用scws实现mysql全文搜索功能的方法
Dec 25 PHP
php实现将wav文件转换成图像文件并在页面中显示的方法
Apr 21 PHP
PHP线程的内存回收问题
Jul 08 PHP
php文件类型MIME对照表(比较全)
Oct 07 PHP
PHP中Notice错误常见解决方法
Apr 28 PHP
PHP实现Markdown文章上传到七牛图床的实例内容
Feb 11 PHP
php+js实现点赞功能的示例详解
Aug 07 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判断浏览器、判断语言代码分享
2015/03/05 PHP
JavaScript与C# Windows应用程序交互方法
2007/06/29 Javascript
Prototype中dom对象方法汇总
2008/09/17 Javascript
分享20款好玩的jQuery游戏
2011/04/17 Javascript
详解javascript中的事件处理
2015/11/06 Javascript
JavaScript获取页面中超链接数量的方法
2015/11/09 Javascript
javascript实现添加附件功能的方法
2015/11/18 Javascript
原生JS实现自定义滚动条效果
2020/10/27 Javascript
js实现控制文件拖拽并获取拖拽内容功能
2018/02/17 Javascript
jQuery实现炫丽的3d旋转星空效果
2018/07/04 jQuery
vue+springboot实现项目的CORS跨域请求
2018/09/05 Javascript
用jQuery将JavaScript对象转换为querystring查询字符串的方法
2018/11/12 jQuery
JS简单判断是否在微信浏览器打开的方法示例
2019/01/08 Javascript
微信小程序实现工作时间段选择
2019/02/15 Javascript
vue中axios的二次封装实例讲解
2019/10/14 Javascript
Python中if __name__ == &quot;__main__&quot;详细解释
2014/10/21 Python
Python Django中间件使用原理及流程分析
2020/06/13 Python
详解查看Python解释器路径的两种方式
2020/10/15 Python
在python3.9下如何安装scrapy的方法
2021/02/03 Python
在PyCharm中安装PaddlePaddle的方法
2021/02/05 Python
CSS3绘制有活力的链接下划线
2016/07/14 HTML / CSS
纽约现代艺术博物馆商店:MoMA STORE(室内家具和杂货商品)
2016/08/02 全球购物
电气工程及其自动化学生实习自我鉴定
2013/09/19 职场文书
师范生实习的个人自我鉴定
2013/10/20 职场文书
应届生会计求职信
2013/11/11 职场文书
护士演讲稿范文
2014/01/05 职场文书
医学生自我评价
2014/01/27 职场文书
2014年纪委工作总结
2014/12/05 职场文书
实习工作表现评语
2014/12/31 职场文书
刑事上诉状范文
2015/05/22 职场文书
新娘婚礼致辞
2015/07/27 职场文书
慰问信的写作格式及范文!
2019/06/24 职场文书
2019最新婚庆对联集锦!
2019/07/10 职场文书
来探秘“德国中小企业”的成功之道
2019/07/26 职场文书
少儿励志名言(80句)
2019/08/14 职场文书
python 判断文件或文件夹是否存在
2022/03/18 Python