Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongo Query question $gt,$lt

Tags:

mongodb

I have a query below. I want get items between 4 and 6 so only a:1 should match because it has the value 5 in b.

> db.test.find({ b : { $gt :  4  }, b: {$lt : 6}}); { "_id" : ObjectId("4d54cff54364000000004331"), "a" : 1, "b" : [ 2, 3, 4, 5 ] } { "_id" : ObjectId("4d54d0074364000000004332"), "a" : 2, "b" : [ 2, 4, 6, 8 ] } > 

Can someone tell be why a:2 is matching this query? I can't really see why it is being returned.

I also tried what was specified in the tutorial but id did not seem to work:

> db.test.find({ b : { $gt :  4, $lt : 6}}); { "_id" : ObjectId("4d54cff54364000000004331"), "a" : 1, "b" : [ 2, 3, 4, 5 ] } { "_id" : ObjectId("4d54d0074364000000004332"), "a" : 2, "b" : [ 2, 4, 6, 8 ] } > 

And this one to avoid any confusion regarding GT/GTE

> db.test.find({b: {$gt: 4.5, $lt: 5.5}}); { "_id" : ObjectId("4d54cff54364000000004331"), "a" : 1, "b" : [ 2, 3, 4, 5 ] } { "_id" : ObjectId("4d54d0074364000000004332"), "a" : 2, "b" : [ 2, 4, 6, 8 ] } > 

only a:1 should be returned.

As suggested, I gave $elemMatch a try but it did not appear to work either (objectIds are different because I am on a different machine)

> db.test.find(); { "_id" : ObjectId("4d5a24a5e82e00000000433f"), "a" : 1, "b" : [ 2, 3, 4, 5 ] } { "_id" : ObjectId("4d5a24bbe82e000000004340"), "a" : 2, "b" : [ 2, 4, 6, 8 ] } > db.test.find({b: {$elemMatch: {$gt : 4, $lt: 6 }}}); > 

No documents were returned.

like image 293
paullb Avatar asked Feb 11 '11 06:02

paullb


People also ask

What is GTE and LT in MongoDB?

Comparison Operators Matches if values are greater than the given value. $lt. Matches if values are less than the given value. $gte. Matches if values are greater or equal to the given value.

What does $GT mean MongoDB?

Overview. $gt means “greater than.” It is a query operator and one of the comparison operators in MongoDB. It selects or matches documents with a path or field value greater than the specified value.


1 Answers

This is a really confusing topic. I work at 10gen and I had to spend a while wrapping my head around it ;)

Let's walk through how the query engine processes this query.

Here's the query again:

> db.test.find({ b : { $gt :  4, $lt : 6}}); 

When it gets to the record that seems like it shouldn't match...

{ "_id" : ObjectId("4d54cff54364000000004331"), "a" : 1, "b" : [ 2, 4, 6, 8 ] } 

The match is not performed against each element of the array, but rather against the array as a whole.

The comparison is performed in three steps:

Step 1: Find all documents where b has a value greater than 4

b: [2,4,6,8] matches because 6 & 8 are greater than 4

Step 2: Find all documents where b has a value less than 6

b: [2,4,6,8] matches because 2 & 4 are less than 6

Step 3: Find the set of documents that matched in both step 1 & 2.

The document with b: [2,4,6,8] matched both steps 1 & 2 so it is returned as a match. Note that results are also de-duplicated in this step, so the same document won't be returned twice.

If you want your query to apply to the individual elements of the array, rather than the array as a whole, you can use the $elemMatch operator. For example

> db.temp.find({b: {$elemMatch: {$gt: 4, $lt: 5}}}) > db.temp.find({b: {$elemMatch: {$gte: 4, $lt: 5}}})   { "_id" : ObjectId("4d558b6f4f0b1e2141b66660"), "b" : [ 2, 3, 4, 5, 6 ] } 
like image 93
jared Avatar answered Oct 02 '22 10:10

jared