如何指定没有结果的MongoDB查询(" WHERE 0 = 1")

时间:2016-10-24 15:55:25

标签: mongodb mongodb-query

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

对于这一点,我需要一些像'" WHERE 0 == 1" MongoDB的子句,即可以与$and$or运算符组合在一起的查询文档,其行为类似于逻辑false,可以通过mongo查询引擎进行优化。

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

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

我也提出{_id: {$exists: false}},但explain()显示查询仍然使用索引扫描。

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

更深入的解释

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

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

如果在我的软件可以自行决定的树的深处有一个条件,它始终是假的,我想尽可能明确地将它设置为Mongo查询引擎。例如,如果所有"中间"文档由$and个运算符组成(因此查询的总结果总是" false"),我希望mongo引擎能够尽快检测到它。

如果我在SQL中执行此操作,则等效项将类似于

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

当SQL引擎获得此查询时,它根本不需要查阅任何索引或表,因为条件可以被证明"总是假的。

3 个答案:

答案 0 :(得分:0)

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

索引创建:

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

查询:

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

我自己没有测试过,所以你可能需要自己测试一下,看看这是否适合你的需要,但我怀疑这是一条值得探索的道路。

答案 1 :(得分:0)

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

在此post中,我解释了为什么应该使用$redact代替$where

根据我的理解,您可以使用$redact运算符执行此操作:

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

$$KEEP$$PRUNE变量是一个系统变量,允许您根据{{3}的重新调整的“保留”或排除所有文档} itional expression。

答案 2 :(得分:0)

在3.6版中,您可以直接表达以下内容:

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