【问题标题】:MongoDB Shell: Error with "$or" query and explain()MongoDB Shell:“$or”查询和解释错误()
【发布时间】:2012-07-23 08:03:31
【问题描述】:

我正在尝试对 MongoDB“$or”查询进行一些分析,但在 Mongo shell 中使用“explain()”命令时遇到问题。当我使用 find 命令运行查询时,它按预期工作并返回一条记录。但是,当我在 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 个结果。我的印象是,无论有无解释(),它们的语法都应该相同,那么我做错了什么?我使用的是 2.0.4 版。感谢任何可以提供帮助的人。

【问题讨论】:

    标签: mongodb mongodb-shell


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

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

      Matt 的回答通过解开您的预包装请求来避免这种情况,这是执行此操作的正常方式...只需在 Matt 的重写末尾添加“.explain()”,它应该可以按您的预期工作。

      如果您想保留您的格式,您只需将“$explain : true”添加到您的文档中,就像使用“$orderby”而不是“.sort”一样。

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

      【讨论】:

      • 天哪,这完全有效。我遇到了同样的问题,除了我使用的是 .count( ) 并且由于完全相同的原因而失败。按照您和 Matt 指定的方式解包查询。谢谢!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-20
      • 2017-11-25
      • 2012-10-26
      • 2020-03-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多