MongoDB Shell:"$或"查询和explain()出错

732*_*732 3 mongodb mongodb-shell

我正在尝试对MongoDB"$或"查询进行一些分析,而我在Mongo shell中遇到'explain()'命令时遇到问题.当我使用find命令运行我的查询时,它会工作并返回一条记录,如预期的那样.当我在find()的末尾添加'explain()'时,我收到以下错误:

未捕获的异常:错误:{"$ err":"无效的运算符:$或","code":10068}

我正在尝试以下查询:

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

如果我将"$或"更改为"或",则explain()工作正常,但查询返回0结果.我的印象是他们的语法应该是相同的,有或没有explain(),所以我做错了什么?我正在使用2.0.4版.感谢任何可能提供帮助的人.

Tad*_*all 6

关键字"查询"在内部用于打包"查询"(查询内容的规范)部分"查询"(请求服务器进行搜索)以使其在发送给BSON文档的BSON文档中保持不同.服务器,但shell帮助程序(如.explain)强制此"打包"发生在您指定的任何内容上.您正在丢失所需的查询(在其中您直接使用"查询"),将其包含在"查询"本身内.

Matt的回答是通过展开你的预先包装的请求来避免这种情况,并且这是正常的做法...只需在Matt的重写结束时添加".explain()"并且它应该按预期工作.

如果你想保留你的格式,你可以像使用"$ orderby"而不是".sort"一样在文档中添加"$ 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
                })
Run Code Online (Sandbox Code Playgroud)

查看shell帮助程序".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;
}
>
Run Code Online (Sandbox Code Playgroud)