程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> PHP綜合 >> PHP驅動MongoDB整數問題的BUG和策略

PHP驅動MongoDB整數問題的BUG和策略

編輯:PHP綜合

那麼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的對應關系:

 

SQL to MongoDB

此外,還有很多資料可供參考,如:MongoDB Aggregation III: Map-Reduce Basics

說明:軟件版本為MongoDB(1.6.5),PECL Mongo(1.1.4)。不同版本結論可能不同。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved