この記事で言及されている整数の問題は、実際には MongoDB の問題ではなく、PHP ドライバーの問題です。MongoDB 自体には 2 つの整数型があります。つまり、32 ビット整数と 64 ビット整数です。 , ただし、古いバージョンの PHP ドライバーでは、オペレーティング システムが 32 ビットか 64 ビットかに関係なく、すべての整数が 32 ビット整数として扱われるため、64 ビット整数は切り捨てられます。可能な限り互換性を維持しながらこの問題を解決するために、新しいバージョンの PHP ドライバーには、64 ビット動作で整数を 64 ビットとして扱うための mongo.native-long オプションが追加されました。興味のある方は、MongoDB の 64 ビット整数 を参照してください。
では、PHP ドライバーは本当に整数の問題を完全に解決できるのでしょうか?いいえ!グループ操作の処理中に バグ があります:
問題を説明するために、まずテスト データを生成してみましょう:
<font face="NSimsun"><?php<br/><br/>ini_set("mongo.native_long", 1);<br/><br/>$instance = new Mongo();<br/><br/>$instance = $instance->selectCollection("test", "test");<br><br>for ($i = 0; $i < 10; $i++) {<br/> $instance->insert(array(<br> "group_id" => rand(1, 5),<br> "count" => rand(1, 5),<br> ));<br>}<br><br>?></font>
|
<font face="NSimsun"><?php<br/><br/>ini_set("mongo.native_long", 1);<br/><br/>$instance = 新しい Mongo ();<br/><br/>$instance = $instance->selectCollection("test", "test");<br><br>for ($i = 0; $i $instance->insert(array(<br> "group_id" => rand(1, 5),<br> "count" => rand(1, 5) ),<br> ));<br>}<br><br>?></font>
|
テーブル>
グループ操作を使用して、group_id に従ってグループ化し、合計の数を計算してみましょう:
<font size="2" face="新宋体"><?php<br/><br/>ini_set("mongo.native_long", 1);<br/><br/>$instance = new Mongo();<br/><br/>$instance = $instance->selectCollection("test", "test");<br><br>$keys = array("group_id" => 1);<br><br>$initial = array("count" => 0);<br><br>$reduce = "<br> function(obj, prev) {<br> prev.count += obj.count;<br> }<br>";<br><br>$result = $instance->group($keys, $initial, $reduce);<br><br>var_dump($result);<br><br>?></font>
|
<font size="2" face="新宋体"><?php<br/><br/>ini_set("mongo.native_long", 1);<br/><br/ >$instance = new Mongo();<br/><br/>$instance = $instance->selectCollection("test", "test");<br/><br/>$keys = array(" group_id" => 1);<br/><br/>$initial = array("count" => 0);<br/><br/>$reduce = "<br/> function(obj, prev) {<br/> prev.count += obj.count;<br/> }<br/>";<br/><br/>$result = $instance->group($keys, $initial 、$reduce);<br/><br/>var_dump($result);<br/><br/>?></font>
|
テーブル>
<font size="2" face="新宋体">ini_set("mongo.native_long", 0);</font>
|
結果は期待されたものと異なります。カウントは蓄積されませんでしたが、[オブジェクト オブジェクト] になりました。現在、グループ操作を使用する必要がある場合、この問題を軽減する 2 つの方法があります。
<font size="2" face="新宋体">$initial = array("count" => (float)0);</font>
|
<font size="2" face="新宋体">ini_set("mongo.native_long", 0);</font>
|
テーブル>
<font size="2" face="新宋体">$initial = array("count" => (float)0);</font>
|
テーブル>
これらの方法は両方とも、根本的な原因ではなく、症状を治療するための便宜的な手段です。現在の PHP ドライバーのグループの実装に問題があるため、それをバイパスし、他の方法を使用して同じ機能を実現します。このメソッドは MapReduce:
です。
<font size="2" face="新宋体"><?php<br/><br/>ini_set("mongo.native_long", 1);<br/><br/>$instance = new Mongo();<br/><br/>$instance = $instance->selectDB("test");<br><br>$map = "<br> function() {<br> emit(this.group_id, this.count);<br> }<br>";<br><br>$reduce = "<br> function(key, values) {<br> var sum = 0;<br><br> for (var index in values) {<br> sum += values[index];<br> }<br><br> return sum;<br> }<br>";<br><br>$result = $instance->command(array(<br> "mapreduce" => "test",<br> "map" => $map,<br> "reduce" => $reduce<br>));<br><br>$result = iterator_to_array($instance->{$result["result"]}->find());<br><br>var_dump($result);<br><br>?></font>
|
<font size="2" face="新宋体"><?php<br/><br/>ini_set("mongo.native_long", 1);<br/><br/ >$instance = new Mongo();<br/><br/>$instance = $instance->selectDB("test");<br/><br/>$map = "<br/> function( ) {<br/> Emit(this.group_id, this.count);<br/> }<br/>";<br/><br/>$reduce = "<br/> function(key, value) {<br/> var sum = 0;<br/><br/> for (値の var インデックス) {<br/> var sum = 0;<br/><br/> }<br/><br/> / > return sum;<br/> }<br/>";<br/><br/>$result = $instance->command(array(<br> "mapreduce" => "test", "map" => $map,<br> "reduce" => $reduce<br>));<br><br>$result = iterator_to_array($instance->; { $result["result"]}->find());<br><br>var_dump($result);<br><br>?></font>
|
テーブル>
象を冷蔵庫に入れるには 3 つのステップが必要ですが、MapReduce を使用する場合は、Map と Reduce の 2 つのステップだけで済みます。次の PDF ドキュメントは、MySQL の GROUP BY と MongoDB の MapReduce の対応関係を明確に示しています。 >
SQL から MongoDB へ
さらに、MongoDB Aggregation III: Map-Reduce Basics
など、参考となる資料が多数あります。
注: ソフトウェアのバージョンは MongoDB (1.6.5)、PECL Mongo (1.1.4) です。バージョンが異なると結論が異なる場合があります。