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的FTP学习(二)
Oct 09 PHP
来自PHP.NET的入门教程
Oct 09 PHP
推荐php模板技术[转]
Jan 04 PHP
php 静态变量与自定义常量的使用方法
Jan 26 PHP
基于PHP常用函数的用法详解
May 10 PHP
解析php利用正则表达式解决采集内容排版的问题
Jun 20 PHP
关于svn冲突的解决方法
Jun 21 PHP
PHP判断是否有Get参数的方法
May 05 PHP
Smarty中的注释和截断功能介绍
Apr 09 PHP
PHP使用正则表达式获取微博中的话题和对象名
Jul 18 PHP
PHP 年月日的三级联动实例代码
May 24 PHP
postman的安装与使用方法(模拟Get和Post请求)
Aug 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
在PHP3中实现SESSION的功能(二)
2006/10/09 PHP
支持php4、php5的mysql数据库操作类
2008/01/10 PHP
关于PHP的curl开启问题探讨
2014/04/08 PHP
php字符串截取函数用法分析
2014/11/25 PHP
一个javascript参数的小问题
2008/03/02 Javascript
jQuery中使用了document和window哪些属性和方法小结
2011/09/13 Javascript
Javascript对象属性方法汇总
2013/11/21 Javascript
js 获取input点选按钮的值的方法
2014/04/14 Javascript
Mac OS X 系统下安装和部署Egret引擎开发环境
2014/09/03 Javascript
JavaScript中的getDay()方法使用详解
2015/06/09 Javascript
详解JavaScript中的客户端消息框架设计原理
2015/06/24 Javascript
基于Javascript实现二级联动菜单效果
2016/03/04 Javascript
浅析C/C++,Java,PHP,JavaScript,Json数组、对象赋值时最后一个元素后面是否可以带逗号
2016/03/22 Javascript
springMVC结合AjaxForm上传文件
2016/07/12 Javascript
JS 实现随机验证码功能
2017/02/15 Javascript
JS实现加载时锁定HTML页面元素的方法
2017/06/24 Javascript
使用vue-router切换页面时,获取上一页url以及当前页面url的方法
2019/05/06 Javascript
微信小程序自定义可滑动顶部TabBar选项卡实现页面切换功能示例
2019/05/14 Javascript
详解利用nodejs对本地json文件进行增删改查
2019/09/20 NodeJs
关于引入vue.js 文件的知识点总结
2020/01/28 Javascript
微信小程序实现简单购物车功能
2020/12/30 Javascript
python中去空格函数的用法
2014/08/21 Python
python中pylint使用方法(pylint代码检查)
2018/04/06 Python
numpy添加新的维度:newaxis的方法
2018/08/02 Python
Python中的random.uniform()函数教程与实例解析
2019/03/02 Python
Python进程间通信Queue消息队列用法分析
2019/05/22 Python
解决python 读取excel时 日期变成数字并加.0的问题
2019/10/08 Python
python GUI库图形界面开发之PyQt5结合Qt Designer创建信号与槽的详细方法与实例
2020/03/08 Python
python--shutil移动文件到另一个路径的操作
2020/07/13 Python
使用Python中tkinter库简单gui界面制作及打包成exe的操作方法(二)
2020/10/12 Python
CSS3实战第一波 让我们尽情的圆角吧
2010/08/27 HTML / CSS
婴儿地球:Baby Earth
2018/12/25 全球购物
我的中国梦演讲稿800字
2014/08/19 职场文书
网络舆情信息简报
2015/07/21 职场文书
乔迁新居祝福语
2019/11/04 职场文书
Windows中Redis安装配置流程并实现远程访问功能
2021/06/07 Redis