ホームページ > php教程 > php手册 > MongoDB の整数の問題を引き起こす PHP のバグと戦略

MongoDB の整数の問題を引き起こす PHP のバグと戦略

WBOY
リリース: 2016-06-21 08:54:58
オリジナル
831 人が閲覧しました

この記事で言及されている整数の問題は、実際には MongoDB の問題ではなく、PHP ドライバーの問題です。MongoDB 自体には 2 つの整数型があります。つまり、32 ビット整数と 64 ビット整数です。 , ただし、古いバージョンの PHP ドライバーでは、オペレーティング システムが 32 ビットか 64 ビットかに関係なく、すべての整数が 32 ビット整数として扱われるため、64 ビット整数は切り捨てられます。可能な限り互換性を維持しながらこの問題を解決するために、新しいバージョンの PHP ドライバーには、64 ビット動作で整数を 64 ビットとして扱うための mongo.native-long オプションが追加されました。興味のある方は、MongoDB の 64 ビット整数 を参照してください。

では、PHP ドライバーは本当に整数の問題を完全に解決できるのでしょうか?いいえ!グループ操作の処理中に バグ があります:

問題を説明するために、まずテスト データを生成してみましょう:

テーブル>

グループ操作を使用して、group_id に従ってグループ化し、合計の数を計算してみましょう:

<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>

<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>
テーブル>

これらの方法は両方とも、根本的な原因ではなく、症状を治療するための便宜的な手段です。現在の PHP ドライバーのグループの実装に問題があるため、それをバイパスし、他の方法を使用して同じ機能を実現します。このメソッドは MapReduce:

です。

<font size="2" face="新宋体">$initial = array("count" => (float)0);</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) です。バージョンが異なると結論が異なる場合があります。



<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>

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のおすすめ
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート