亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

Chinaunix

標(biāo)題: PHP操作MongoDB時(shí)的整數(shù)問題及對策 [打印本頁]

作者: 三里屯搖滾    時(shí)間: 2012-02-23 19:03
標(biāo)題: PHP操作MongoDB時(shí)的整數(shù)問題及對策
]
PHP操作MongoDB時(shí)的整數(shù)問題及對策





本文是一篇轉(zhuǎn)載文章,對MongoDB PHP驅(qū)動中的一個(gè)bug進(jìn)行了描述,其間對MongoDB和Group操作和MapReduce操作都給出了典型的例子,值得一看。

原文鏈接:http://huoding.com/2011/03/13/55

本文所說的整數(shù)問題,其實(shí)并不是MongoDB的問題,而是PHP驅(qū)動的問題:MongoDB本身有兩種整數(shù)類型,分別是:32位整數(shù)和64位整數(shù),但舊版的PHP驅(qū)動不管操作系統(tǒng)是32位還是64位,把所有整數(shù)都當(dāng)做32位整數(shù)處理,結(jié)果導(dǎo)致64位整數(shù)被截?cái)。為了在盡可能保持兼容性的前提下解決這個(gè)問題,新版PHP驅(qū)動加入了mongo.native-long選項(xiàng),以期在64位操作系統(tǒng)中把整數(shù)都當(dāng)做64位來處理,有興趣的可參考:64-bit integers in MongoDB。

那么PHP驅(qū)動真的完全解決了整數(shù)問題么?NO!在處理group操作的時(shí)候還有BUG:

為了說明問題,我們先來生成一些測試數(shù)據(jù):
  1. selectCollection('test', 'test');

  2. for ($i = 0; $i < 10; $i++) {
  3.     $instance->insert(array(
  4.         'group_id' => rand(1, 5),
  5.         'count'    => rand(1, 5),
  6.     ));
  7. }
  8. ?>下面讓我們使用group操作,根據(jù)group_id分組,匯總計(jì)算count:

  9. selectCollection('test', 'test');
  10. $keys = array('group_id' => 1);
  11. $initial = array('count' => 0);

  12. $reduce = '
  13.     function(obj, prev) {
  14.         prev.count += obj.count;
  15.     }
  16. ';

  17. $result = $instance->group($keys, $initial, $reduce);
  18. var_dump($result);
復(fù)制代碼
?>結(jié)果和預(yù)想的有出入,count沒有實(shí)現(xiàn)累加,而是變成了[object Object],目前,如果必須使用group操作,那么有兩種方法可以緩解這個(gè)問題:

方法一:

ini_set('mongo.native_long', 0);方法二:

$initial = array('count' => (float)0);這兩種方法都是治標(biāo)不治本的權(quán)宜之計(jì),既然當(dāng)前PHP驅(qū)動里group的實(shí)現(xiàn)有問題,那我們就繞開它,用其它的方式實(shí)現(xiàn)同樣的功能,這個(gè)方式就是MapReduce:
  1. selectDB('test');

  2. $map = '
  3.     function() {
  4.         emit(this.group_id, this.count);
  5.     }
  6. ';

  7. $reduce = '
  8.     function(key, values) {
  9.         var sum = 0;

  10.         for (var index in values) {
  11.             sum += values[index];
  12.         }

  13.         return sum;
  14.     }
  15. ';

  16. $result = $instance->command(array(
  17.     'mapreduce' => 'test',
  18.     'out'       => 'name',
  19.     'map'       => $map,
  20.     'reduce'    => $reduce
  21. ));

  22. $result = iterator_to_array($instance->{$result['result']}->find());
  23. var_dump($result);
  24. ?>
復(fù)制代碼
說明:雖然從表面上看MapReduce要生成一個(gè)新的Collection,顯得有些低效,但我們可以定期預(yù)生成它,相當(dāng)于維護(hù)一個(gè)緩存表,只要對實(shí)時(shí)性要求不太高就沒問題。

把大象放冰箱里需要三步,而使用MapReduce僅僅需要Map和Reduce兩步即可,這里有一個(gè)PDF文檔生動的說明了MySQL中GROUP BY和MongoDB中MapReduce的對應(yīng)關(guān)系:



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

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


作者: 冰釋一片天    時(shí)間: 2012-02-24 17:06
希望與樓至多多交流




歡迎光臨 Chinaunix (http://72891.cn/) Powered by Discuz! X3.2