3

MongoDBの「$or」クエリのプロファイリングを実行しようとしていますが、Mongoシェルの「explain()」コマンドで問題が発生しています。findコマンドを使用してクエリを実行すると、期待どおりに機能し、1つのレコードが返されます。ただし、find()の最後で「explain()」を追加すると、次のエラーが発生します。

キャッチされない例外:エラー:{"$ err": "無効な演算子:$ or"、 "コード":10068}

私は次のクエリを試しています:

db.people.find({"query" : 
                   {"$or" : [ 
                       {"site" : "mysite", "site_id" : "587125722"}, 
                       {"user_id" : ObjectId("4fb811aae4b0b628b485a58d")}
                   ]}, 
                "$orderby" : { "global_id" : 1, "user_id" : 1}
                })

「$or」を「or」に変更すると、explain()は正常に機能しますが、クエリは0の結果を返します。Explain()の有無にかかわらず、構文は同じである必要があるという印象を受けましたが、何が間違っているのでしょうか。バージョン2.0.4を使用しています。助けることができるかもしれない誰にでも感謝します。

4

2 に答える 2

6

キーワード「query」は、「query」(検索を実行するためのサーバーへの要求)の「query」(検索対象の指定)部分をパッケージ化して、に送信されるBSONドキュメント内で区別できるようにするために内部的に使用されます。サーバーですが、シェルヘルパー(.explainなど)は、この「パッケージ化」を指定したものに強制的に実行します。「クエリ」自体の中にラップされて、目的のクエリ(「クエリ」を直接使用した)が失われます。

Mattの回答は、事前にラップされたリクエストをアンラップすることでこれを回避します。これを行う通常の方法です... Mattの書き換えの最後に「.explain()」を追加するだけで、期待どおりに機能するはずです。

フォーマットを維持したい場合は、「。sort」の代わりに「$ orderby」を使用したのと同じ方法で、ドキュメントに「$ Explain:true」を追加できます。

db.people.find({"query" : 
                   {"$or" : [ 
                       {"site" : "mysite", "site_id" : "587125722"}, 
                       {"user_id" : ObjectId("4fb811aae4b0b628b485a58d")}
                   ]}, 
                "$orderby" : { "global_id" : 1, "user_id" : 1},
                "$explain" : true
                })

シェルヘルパー「.explain」のJavaScriptコードを見て、その機能を確認してください。

> db.foo.find().explain
function (verbose) {
    var n = this.clone();
    n._ensureSpecial();
    n._query.$explain = true;
    n._limit = Math.abs(n._limit) * -1;
    var e = n.next();

    function cleanup(obj) {
        if (typeof obj != "object") {
            return;
        }
        delete obj.allPlans;
        delete obj.oldPlan;
        if (typeof obj.length == "number") {
            for (var i = 0; i < obj.length; i++) {
                cleanup(obj[i]);
            }
        }
        if (obj.shards) {
            for (var key in obj.shards) {
                cleanup(obj.shards[key]);
            }
        }
        if (obj.clauses) {
            cleanup(obj.clauses);
        }
    }

    if (!verbose) {
        cleanup(e);
    }
    return e;
}
> db.foo.find()._ensureSpecial
function () {
    if (this._special) {
        return;
    }
    var n = {query:this._query};
    this._query = n;
    this._special = true;
}
>
于 2012-07-25T01:47:16.187 に答える
1

あなたはおそらく混同しているrunCommand()find()。これを試して:

db.people.find( { "$or" : [ { site : "mysite", site_id : "587125722" }, 
                            { user_id : ObjectId("4fb811aae4b0b628b485a58d") } ] }
              ).sort( { global_id : 1, user_id : 1 } )
于 2012-07-24T22:59:54.397 に答える