使用しているMongoDBのリリースについては言及していませんが、解決方法はここに示したものと似ています。 Ubuntu 13.04に付属している2.2.4上でデモンストレーションします。
これを行う問題は、実際にはオプションをカーソルに挿入していることです。
> var cursor = db.test.find()
> cursor.addOption
function (option) {
this._options |= option;
return this;
}
のはmapReduce
が定義されている方法を見てみましょう:
> db.test.mapReduce
function (map, reduce, optionsOrOutString) {
var c = {mapreduce:this._shortName, map:map, reduce:reduce};
...
var raw = this._db.runCommand(c);
...
return new MapReduceResult(this._db, raw);
}
だから、runCommand
経由でコマンドを実行するには、ドキュメントを作成しますaddOption
命はどこです。さらにそれに見てみましょう:
> db.runCommand
function (obj) {
if (typeof obj == "string") {
var n = {};
n[obj] = 1;
obj = n;
}
return this.getCollection("$cmd").findOne(obj);
}
だから、コマンドがfindOne
を経由して実行されます。それを見てみましょう:
> db.test.findOne
function (query, fields, options) {
var cursor = this._mongo.find(this._fullName, this._massageObject(query) || {}, fields, -1, 0, 0, options || this.getQueryOptions());
if (!cursor.hasNext()) {
return null;
}
var ret = cursor.next();
...
return ret;
}
ああ、ここに興味深いものがあります。カーソルはパラメータoptions
からのフラグで初期化されていますが、runCommand
は設定されていないため、残念ながらあなたのケースを助けませんが、コレクションからのgetQueryOptions()
とORします。それを見てみましょう:
> db.collection.getQueryOptions
function() {
var options = 0;
if (this.getSlaveOk()) {
options |= 4;
}
return options;
}
おっと。いいですね。したがって、私たちはカーソルにアクセスすることはできません。また、非ハッキング手段を介して実行されたコマンドにクエリオプションを注入する方法もありません。
マップリダクションコマンドが実際にそのプロセスを通じてサーバーに配信される方法については、十分に理解しました。これは、データベース内の特定のコレクションに対して照会される単なるドキュメントです。つまり、同じクエリを作成して実行することができますが、必要なフラグを指定することができます。
MongoDBコマンド全体をビルドして結果を設定するのは難しいことではありませんが、実際にはisMaster
コマンドを使って実際に動作することを示しています。
これは、任意のフラグなしで実行するコマンドです:
> db.getCollection("$cmd").findOne({isMaster: 1}).ismaster
true
効果の違いを確認するために、我々は、データベースとの通信をtcpdumpのでしょう。
. vvvvvvvvv
0x0040: d407 0000 0000 0000 7465 7374 2e24 636d ........test.$cm
0x0050: 6400 0000 0000 ffff ffff 1700 0000 0169 d..............i
グッド:それはダンプの関連する部分を見つけることは簡単ですので、私たちは、32ビットの整数で、該当するフラグが右のコレクション名の前に住んでいることthe wire protocol documentationで見ることができます。コレクション名の直前に、4バイトがゼロであることがわかります。
ここで、いくつかのフラグを提供しながら同じことをやりましょう。我々は、クエリフラグがfindOne
の第三の選択肢として提供することができることは、上記のデバッグセクションから学んだ、それではそれをやらせるしました:
> db.getCollection("$cmd").findOne({isMaster: 1}, undefined, 0xBEEF).ismaster
true
とダンプ参照:ねえ
. vvvvvvvvv
0x0040: d407 0000 efbe 0000 7465 7374 2e24 636d ........test.$cm
0x0050: 6400 0000 0000 ffff ffff 1700 0000 0169 d..............i
を、私たちのフラグはどこにあるのかが分かりました。反転していることもわかります。つまり、バイトがリトルエンディアンとしてエンコードされており、一致するのはthe docsです。
それで、あなたは第三findOne
のオプション、および手のコードとしてフラグDBQuery.Option.noTimeout
を提供できることを意味し、そのマップ-減らすコマンド我々はisMaster
で行ったものと同様の方法でin the documentationを説明し、あなたは何を買ってあげるとあなたは欲しい。