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

时间:2012-07-24 22:51:12

标签: mongodb mongodb-shell

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

  

未捕获的异常:错误:{“$ err”:“运营商无效:$或”,“代码”:10068}

我正在尝试以下查询:

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

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

2 个答案:

答案 0 :(得分:6)

关键字“查询”在内部用于打包“查询”(搜索内容的规范)部分“查询”(请求服务器进行搜索)以使其在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
                })

查看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;
}
>

答案 1 :(得分:1)

您可能会混淆runCommand()find()。试试这个:

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