【问题标题】:How to specify a MongoDB query with no results ("WHERE 0=1")如何指定没有结果的 MongoDB 查询(“WHERE 0=1”)
【发布时间】:2017-03-06 11:30:11
【问题描述】:

我正在开发一种将业务领域中的查询转换为 MongoDB 查询文档的软件。

为此,我需要一些类似于 MongoDB 的“WHERE 0==1”子句的想法,即可以与 $and$or 运算符组合的查询文档,其行为类似于逻辑 false 并且可以优化由 mongo 查询引擎。

这样,如果查询构建器的某个子部分检测到“不可能”条件,它可以只返回这个“假”查询文档,让 mongodb 引擎忽略查询语法树的相应分支。

{$where: "false"} 可以解决问题,但在这种情况下,mongoDB 引擎似乎对结果的每一行都评估“假”(而不是简单地返回一个空结果集)。

我也想出了{_id: {$exists: false}},但是explain() 表明查询仍然使用索引扫描。

所以我很好奇是否有任何其他选项可以获得空结果集。

更深层次的解释

我的软件的用户将能够以特定领域的查询语言定义查询,这将被翻译成一个相当复杂的 mongodb 查询文档。该查询基本上将具有{$and: [ {$or: [ {},{$and: ...},...]}]} 的形式,因此这是一个深度嵌套的、相当复杂的条件树。

目前树的构造很简单,因为域查询的每个元素或多或少都可以很好地转换为相应的 Mongo 查询。

如果在树的深处有一个条件,我的软件可以自行决定它总是错误的,我想让 Mongo 查询引擎尽可能明确地说明这一点。因此,例如,如果所有“中间”文档都包含 $and 运算符(因此查询的总体结果将始终为“假”),我希望 mongo 引擎尽快检测到这一点。

如果我在 SQL 中执行此操作,则相当于

SELECT  * FROM TABLE WHERE C1 AND C2 AND (C3 OR C4) AND ... AND (1=0)

当 SQL 引擎得到这个查询时,它根本不需要查询任何索引或表,因为可以“证明”该条件始终为假。

【问题讨论】:

  • 排除所有字段的投影?
  • 你的问题很难理解。您能否展示具有预期结果的示例文档?
  • @Styvane 对不起我的英语;)我试图添加一些额外的解释。基本上我的查询是自动构建的,我正在寻找某种方法让 Mongo 优化“不可能”的条件......

标签: mongodb mongodb-query


【解决方案1】:

3.6版本可以直接表达:

{ $expr: { $eq: [0, 1] } }

【讨论】:

    【解决方案2】:

    索引扫描将是您在解释查询中看到的最快的操作之一。使这更快的一种选择是创建一个稀疏索引,然后通过提示强制您的查询使用该索引。

    所以索引创建:

    db.myCollection.createIndex( { "does_not_exist": 1 }, { sparse: true })
    

    查询:

    db.myCollection.find(
        {  "does_not_exist": 
              { $exists: true }, 
           $hint: 
              {does_not_exist : 1}
        })
    

    我自己没有对此进行测试,因此您可能需要自己进行一些测试,看看这是否适合您的需求,但我怀疑这是一条值得探索的道路。

    【讨论】:

      【解决方案3】:

      首先,您应该只使用$where 运算符,并且仅当您的问题无法使用任何其他查询运算符解决时。但是根据我的经验,如果$where 可以做到,那么$redact 会做得更好,除非您的架构设计非常糟糕,或者正在做一些您不应该在查询表达式中做的事情。

      在这个post 中,我解释了为什么应该使用$redact 而不是$where

      按照我的理解,您可以像这样使用$redact 运算符来做到这一点:

      db.collection.aggregate([
          { "$redact": { 
              "$cond": [ 
                  { "$eq": [true, false]}, 
                  "$$KEEP", 
                  "$$PRUNE"
              ]
          }}
       ])
      

      $$KEEP$$PRUNE 变量是一个系统变量,允许您根据$conditional 表达式的重新调整的“保留”或排除所有文档。 p>

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-12-04
        相关资源
        最近更新 更多