Mongodb在隐式AND中发现方法混淆

Posted

技术标签:

【中文标题】Mongodb在隐式AND中发现方法混淆【英文标题】:Mongo DB find method confusion in Implicit AND 【发布时间】:2014-11-03 18:45:16 【问题描述】:

我是 mongodb 新手,最近开始学习基本语法。我正在尝试使用 find 方法的运算符,但在尝试隐式 AND 时遇到了一个令人困惑的情况。

我的收藏mathtable400个文档如下:

 "_id" : ObjectId("540efc2bd8af78d9b0f5d4b2")  , "index" : 1   
 "_id" : ObjectId("540efc2bd8af78d9b0f5d4b3")  , "index" : 2   
 "_id" : ObjectId("540efc2bd8af78d9b0f5d4b4")  , "index" : 3   
 "_id" : ObjectId("540efc2bd8af78d9b0f5d4b5")  , "index" : 4   
 "_id" : ObjectId("540efc2bd8af78d9b0f5d4b6")  , "index" : 5   
 "_id" : ObjectId("540efc2bd8af78d9b0f5d4b7")  , "index" : 6   
 "_id" : ObjectId("540efc2bd8af78d9b0f5d4b8")  , "index" : 7   
 "_id" : ObjectId("540efc2bd8af78d9b0f5d4b9")  , "index" : 8   
 "_id" : ObjectId("540efc2bd8af78d9b0f5d4ba")  , "index" : 9   
 "_id" : ObjectId("540efc2bd8af78d9b0f5d4bb")  , "index" : 10  
 "_id" : ObjectId("540efc2bd8af78d9b0f5d4bc")  , "index" : 11  
 "_id" : ObjectId("540efc2bd8af78d9b0f5d4bd")  , "index" : 12  
 "_id" : ObjectId("540efc2bd8af78d9b0f5d4be")  , "index" : 13  
 "_id" : ObjectId("540efc2bd8af78d9b0f5d4bf")  , "index" : 14  
 "_id" : ObjectId("540efc2bd8af78d9b0f5d4c0")  , "index" : 15  
 "_id" : ObjectId("540efc2bd8af78d9b0f5d4c1")  , "index" : 16  
 "_id" : ObjectId("540efc2bd8af78d9b0f5d4c2")  , "index" : 17  
 "_id" : ObjectId("540efc2bd8af78d9b0f5d4c3")  , "index" : 18  
 "_id" : ObjectId("540efc2bd8af78d9b0f5d4c4")  , "index" : 19  
 "_id" : ObjectId("540efc2bd8af78d9b0f5d4c5")  , "index" : 20  
 "_id" : ObjectId("540efc2bd8af78d9b0f5d4d1")  , "index" : 1   
..
..
 "_id" : ObjectId("540efc2bd8af78d9b0f5d4z5")  , "index" : 20 

mathtable 集合中有 400 行:

index 的值范围为 1 to 20。 对于index 的每个值,都有20 具有不同_id 值的条目。

考虑到它们都是implicit AND 案例,我正在尝试以下两种操作并期望得到相同的结果。

甚至计算大于 5 的 index 值。

使用经典的 EXPLICIT AND(结果为 160 条记录):

 db.mathtable.count( 
            $and: [
             index:  $mod: [2,0]  ,         
             index:  $gt: 5       
            ] 
        );

只使用一次变量名(结果为 160 条记录):

db.mathtable.count( 
                  index :  $mod : [2,0] ,  $gt:5  
                  );

对每个条件使用字段名称(结果为 300 条记录):

db.mathtable.find( 
                  index :  $mod : [2,0] , 
                  index : $gt:5 
                 );

对每个条件使用字段名称,条件相反(结果为 200 条记录):

db.mathtable.find( 
                  index :  $gt:5 , 
                  index :  $mod : [2,0]
                 );

在 mongoDB 文档中没有提到 implicit OR(或者至少我没有找到像 implicit AND 这样的直接参考)。

在这两种情况下,我期望的记录数相同 (160)。我无法理解为什么上面的代码表现不同。

此外,条件规范的顺序会产生不同数量的结果。根据观察,当多次指定同一字段时,仅应用了 find 中指定的最后一个条件。 这很奇怪且不正确。

注意:我正在使用Mongo-DB-2.6,代码正在分发中的mongo shell 上执行。

【问题讨论】:

【参考方案1】:

Json 或关联数组或映射 does not 包含重复键:

db.mathtable.find( 
                  index :  $mod : [2,0] , 
                  index : $gt:5 
                 );

以上将被视为等同于:

db.mathtable.find( 
                  index : $gt:5 
                 );

第一个条件会被覆盖,

以下,

db.mathtable.find( 
                  index :  $gt:5 , 
                  index :  $mod : [2,0]
                 );

将等同于,

db.mathtable.find( 
                  index :  $mod : [2,0]
                 );

但是在第一种情况下,

db.mathtable.count( 
            $and: [
             index:  $mod: [2,0]  ,         
             index:  $gt: 5       
            ] 
        );

$and 将两个 json 文档作为输入并按预期运行。

在第二种情况下,count 采用没有重复键的单个文档并按预期运行。

db.mathtable.count( 
                  index :  $mod : [2,0] ,  $gt:5  
                  );

因此返回的行数不同。希望它是有帮助的。

【讨论】:

这对理解原因很有帮助。

以上是关于Mongodb在隐式AND中发现方法混淆的主要内容,如果未能解决你的问题,请参考以下文章

Swift Xcode 致命错误:在隐式展开可选值时意外发现 nil [重复]

iOS/Xcode:Koloda 框架:在隐式展开 Optional 值时意外发现 nil

在隐式展开可选值时意外发现 nil (UICollectionView)

Swift:错误:在隐式展开可选值时意外发现 nil

在隐式展开可选值 AVAUDIO Player SWIFT 时意外发现 nil

UITableViewCell 中的 AVPlayer 导致“在隐式展开可选值时意外发现 nil”错误