3

我正在尝试对 MongoDB "$or" 查询进行一些分析,但在 Mongo shell 中使用 'explain()' 命令时遇到问题。当我使用 find 命令运行查询时,它按预期工作并返回一条记录。但是,当我在 find() 末尾添加“explain()”时,出现以下错误:

未捕获的异常:错误:{“$err”:“无效运算符:$or”,“code”: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 个结果。我的印象是,无论有无解释(),它们的语法都应该相同,那么我做错了什么?我使用的是 2.0.4 版。感谢任何能够提供帮助的人。

4

2 回答 2

6

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

马特的回答通过解开您的预先包装的请求来避免这种情况,并且是这样做的正常方式......只需在马特的重写末尾添加“.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;
}
>
于 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 回答