2012-07-24 23 views
3

我试图做一些MongoDB“$或”查询的分析,我在Mongo中的'explain()'命令有问题贝壳。当我使用find命令运行我的查询时,它可以正常工作并返回一条记录。当我钉在了“解释()”在查找结束(),但是,我得到以下错误:

uncaught exception: error: { "$err" : "invalid operator: $or", "code" : 10068 }

我想下面的查询:

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

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

回答

6

“查询”用于内部打包“查询”(什么搜索规范)“查询”部分(请求给服务器做搜索)的关键字在发送给服务器的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 
       }) 

看的外壳助手的JavaScript代码 “.explain”,看看它做什么:

> 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; 
} 
> 
+0

妈呀,这是完全奏效。除了使用 .count()之外,我遇到了同样的问题,并且出于完全相同的原因而失败。按照您和Matt指定的方式正确解包查询。谢谢! – 2017-01-08 07:42:45

1

您可能在混合runCommand()find()。试试这个:

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