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.
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.
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.
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 ] }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With