Trouble understanding implicit "$and" and logic query operators

in “Chapter 4: Advanced CRUD Operations” > “Query Operators - Logic”, the following is shown:

image

However, when I tried them both using the shell, I get different results.

db.grades.find(
   {"student_id": {"$gt": 25}},
   {"student_id": {"$lt": 100}}
).count() // returns 99740

db.grades.find(
	{"student_id": {"$gt": 25, "$lt": 100}}
).count() // returns 740

What am I missing here?

In

db.grades.find(
    {"student_id": {"$gt": 25}},
    {"student_id": {"$lt": 100}}
).count()

you are passing 2 arguments to find(). Which according to db.collection.find() — MongoDB Manual, the first one is a query and the other a projection.

What you are missing is the $and so that both objects become the clauses of an explicit $and. It should be

db.grades.find( { "$and" : [
    {"student_id": {"$gt": 25}},
    {"student_id": {"$lt": 100}}
] } ).count()
1 Like

So the example is wrong?

There are things that are not correct. But what they really wanted to say is that

$and : [ FieldQueryOne , FieldQueryTwo ]

is logically the same as

FieldQueryOne , FieldQueryTwo.

I wrote logically, because the syntax has to be adjusted and there are exceptions.

For example:

$and : [ { field_one : value_one } , { field_two : value_two } ]

is equivalent to

{ field_one : value_one , field_two : value_two }

The braces have to be adjusted to form a valid JSON document.

As for some of the exceptions, field_one and field_two cannot be the same field name as you cannot have 2 fields with the same name in the same document. For example, if you have

{ field_name : value_one , field_name : value_two }

it is the same as

{ field_name : value_two }
1 Like

Nice. Thanks for your help, it makes sense now!
If any staff sees this, I guess the video example could be fixed to be a bit more explanatory. But thanks for everything!

Thanks, i got that too

db.grades.find({$and:[{“student_id”:{$gt: 25}},{“student_id”:{$lt: 100}}]}).count()

740

db.grades.find({“student_id”:{$gt: 25},“student_id”:{$lt: 100}}).count()

1000

db.grades.find({“student_id”:{$gt: 25, $lt: 100}}).count()

740

Welcome to the community @londoso!

As @steevej pointed out in an earlier comment, you cannot have duplicate field names or properties at the same level in a JavaScript object. If you set the same property (field name or operator) multiple times, JavaScript interpreters will generally use the last value set.

This is more obvious if you try creating an object for your second query in the mongo shell:

> query = {"student_id":{$gt: 25},"student_id":{$lt: 100}}
{ "student_id" : { "$lt" : 100 } }

To repeat a field or operator at the same level in a query, you need to use an explicit $and: AND Queries With Multiple Expressions Specifying the Same Field.

Regards,
Stennie

1 Like