Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongo DB find method confusion in Implicit AND

I am new to mongodb I have started to learn basic syntax recently. I was trying operators with find method, and I got a confusing case while trying Implicit AND.

My Collection mathtable having 400 documents is as follows:

{ "_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 }

There are 400 rows in mathtable collection:

  • Value of index ranges from 1 to 20.
  • For each value of index there are 20 entries with different _id value.

I am trying below two operations and expecting same results, considering that they are both implicit AND cases.

Calculating even index values having a value greater than 5.

  • Using classic EXPLICIT AND ( results into 160 records ) :

     db.mathtable.count({ 
                $and: [
                { index: { $mod: [2,0] } },         
                { index: { $gt: 5 } }     
                ] 
            });
    
  • Using variable name only once ( results into 160 records ) :

    db.mathtable.count({ 
                      index : { $mod : [2,0] ,  $gt:5 } 
                      });
    
  • Using field name with every condition ( results into 300 records ):

    db.mathtable.find({ 
                      index : { $mod : [2,0]} , 
                      index : {$gt:5} 
                     });
    
  • Using field name with every condition, conditions in opposite order ( results into 200 records ):

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

There is no mention of implicit OR in mongoDB documentation( or at-least I did not find a direct reference like implicit AND ) .

I was expecting same count of records ( 160 ) in both cases. I am unable to understand why above codes are behaving differently.

Also, order of condition specification results into different number of results. As per observation, only the last condition specified in find was applied, when same field was specified multiple times. That is weird and incorrect.

NOTE: I am using Mongo-DB-2.6 and code is being executed on mongo shell that comes with the distribution.

like image 352
Learn More Avatar asked Sep 10 '14 07:09

Learn More


1 Answers

Json or an associative array or a map does not contain duplicate keys:

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

The above will be considered equivalent to:

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

The first condition will be overwritten,

and the below,

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

will be equivalent to,

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

However in the first case,

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

the $and takes two json documents as input and behaves as expected.

and in the second case, count takes a single document with no duplicate keys and behaves as expected.

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

Hence the difference in the number of rows returned. Hope it is helpful.

like image 76
BatScream Avatar answered Oct 01 '22 04:10

BatScream