0

mongodb 2.4.3 win32 で PHP を使用して奇妙な動作を理解しようとしています。サーバー側でシーケンス ID を生成しようとしています。

保存された関数をパラメーターの 1 つとして使用してドキュメントを挿入すると、保存された関数が挿入ごとに数回呼び出されるように見えます。

次のように初期化されたカウンターがあるとしましょう。

db.counters.insert( { _id: "uqid", seq: NumberLong(0) } );

次のように定義されている getUqid という名前のストアド関数があります

db.system.js.save( 
    { _id: "getUqid", 
      value: function () { 
                  var ret = db.counters.findAndModify(
                  { query: { _id: "uqid" }, 
                    update: { $inc: { seq: NumberLong(1) } }, 
                    new: true 
                  } );
                  return ret.seq; 
                  } 
             }  );

このように 3 つの挿入を行うと、次のようになります。

$conn->test->ads->insert(['qid' => new MongoCode('getUqid()') , 'name' => "Sarah C."]);

私はそのようなものを得ます:

db.ads.find()
{ "_id" : ObjectId("51a34f8bf0774cac03000000"), "qid" : 17, "name" : "Sarah C." }
{ "_id" : ObjectId("51a34f8bf0774cac03000001"), "qid" : 20, "name" : "Michel D." }
{ "_id" : ObjectId("51a34f8bf0774cac03000002"), "qid" : 23, "name" : "Robert U." }

qidが 3ずつステップアップしている理由の手がかりはありますか? 保存された関数への 3 つの呼び出しを受け取ったことを意味するはずですよね?

よろしくお願いします。

PS:二次的な質問: NumberLong は、内部の mongodb ストレージに 64 ビットの符号なし整数があることを確認するためにまだ必要ですか? シェルでそれをクロスチェックするコマンドはありますか?

4

1 に答える 1

1

この質問をPHP-841と相互参照します。PHP 側から見ると、実際にはフィールドにBSON コード値qidを格納しています。データベースから結果を取得するとき、またはコマンドでデータベースのエクスポートを実行するときに、おそらく確認できますmongodump

問題は、表示時にコード タイプを誤って評価する JS シェルにあり、それがfindAndModifyが実行されるポイントです。この修正は、後続のサーバー リリースに含まれる必要があります。

それまでの間、PHPから呼び出すという Sammaye の提案findAndModifyは、この種の機能に最適なオプションです。偶然にも、これは Doctrine MongoDB ODM で行われていることでもあります ( IncrementGeneratorを参照)。サーバーへの追加のラウンド トリップが必要ですが、MongoDB には書き込み操作中に JS コールバックを実行する機能がないため、これは必要です。

MongoDB へのラウンドトリップを最小限に抑えることが最も重要である場合は、MongoDB::execute()を使用して PHP を介してサーバー側の JS を実行し、生成された ID をコマンド応答として返すなどの操作を行って、ドキュメントを挿入できます。もちろん、これは一般的にはお勧めできません。JS の評価には独自の注意事項があります。

于 2013-06-24T20:30:25.520 に答える