使用している MongoDB のリリースについて言及していませんが、解決策はここで提示されているものと似ています。Ubuntu 13.04 に付属する 2.2.4 の上でデモンストレーションを行います。
これを行う際の問題は、実際にオプションをカーソルに挿入することです。それがaddOption
命の場所です:
> 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
。さらに詳しく見てみましょう。
> 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
で OR します。getQueryOptions()
それを見てみましょう:
> db.collection.getQueryOptions
function () {
var options = 0;
if (this.getSlaveOk()) {
options |= 4;
}
return options;
}
おっと..それはダメです。そのため、カーソルにアクセスすることも、実行されたコマンドに非ハッキング手段でクエリ オプションを挿入する方法もありません。
まあ、しかし、map reduce コマンドが実際にそのプロセスを通じてどのようにサーバーに配信されるかについて、多くのことを学びました。これは、データベース内の特定のコレクションに対してクエリが実行される単なるドキュメントです。つまり、同じクエリを作成して自分で実行できますが、必要なフラグを提供できます。
MongoDB コマンド全体を作成して結果をセットアップするという問題については説明しませんが、isMaster
コマンドを使用して実際に機能することを示すだけにとどめます。
これは、フラグなしで実行されるコマンドです。
> db.getCollection("$cmd").findOne({isMaster: 1}).ismaster
true
効果の違いを確認するために、データベースとの通信を tcpdump します。ワイヤ プロトコルのドキュメントで、関連するフラグがコレクション名の直前に 32 ビット整数で存在することがわかります。そのため、ダンプの関連部分を簡単に見つけることができます。
. vvvvvvvvv
0x0040: d407 0000 0000 0000 7465 7374 2e24 636d ........test.$cm
0x0050: 6400 0000 0000 ffff ffff 1700 0000 0169 d..............i
良い。コレクション名の直前にある 4 バイトがゼロになっていることがわかります。
さて、いくつかのフラグを提供しながら同じことをしましょう。上記のデバッグ セクションから、クエリ フラグを の 3 番目のオプションとして提供できることがわかった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
ねえ、私たちのフラグは必要な場所に配信されました。また、逆になっていることもわかります。つまり、バイトはリトルエンディアンとしてエンコードされ、 docsと一致します。
つまり、フラグDBQuery.Option.noTimeout
を の 3 番目のオプションとして提供し、ドキュメントで説明されているように、 で行ったのと同様の方法でfindOne
map-reduce コマンドをハンドコーディングすると、必要なものが得られます。isMaster