首页 文章

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

提问于
浏览
1

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

为此,我需要像MongoDB的"WHERE 0==1"子句那样思考,即可以与 $and$or 运算符组合的查询文档,其行为类似于逻辑 false ,可以通过mongo查询引擎进行优化 .

这样,如果查询构建器的某个子部分检测到“不可能”的情况,它可能只返回此“错误”查询文档,并让mongodb引擎忽略查询语法树的相应分支 .

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

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

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

Deeper Explanation

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

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

如果's one condition deep down the tree where the my software can decide on its own that it'总是错误的话我想尽可能明确地将它设置为Mongo查询引擎 . 因此,例如,如果所有"intermediate"文档都由 $and 运算符组成(因此查询的总结果总是"false"),我希望mongo引擎能够尽快检测到它 .

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

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

当SQL引擎获得此查询时,它根本不需要查询任何索引或表,因为条件可以“证明”始终为false .

2 回答

  • 0

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

    索引创建:

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

    查询:

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

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

  • 0

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

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

    据我所知,你可以使用 $redact 运算符这样做:

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

    $$KEEP$$PRUNE变量是一个系统变量,允许您根据$cond itional表达式的重新调整的值"keep"或排除所有文档 .

相关问题