MongoDB $and Aggregation Pipeline Operator

In MongoDB, the $and aggregation pipeline operator evaluates one or more expressions and returns true if they all evaluate to true, or if its invoked with no arguments. Otherwise it returns false.

Syntax

The syntax goes like this:

{ $and: [ <expression1>, <expression2>, ... ] }

Example

Suppose we have a collection called data with the following document:

{ "_id" : 1, "a" : 10, "b" : 2, "c" : 20 }

Here’s what happens when we use $and to test for two conditions against that document:

db.data.aggregate(
   [
     { $match: { _id: 1 } },
     { $project: { 
        _id: 0,
        a: 1,
        b: 1,
        result: { $and: [ 
              { $gt: [ "$a", 9 ] }, 
              { $lt: [ "$b", 3 ] } 
            ] } 
          } 
         }
   ]
)

Result:

{ "a" : 10, "b" : 2, "result" : true }

We can see that $and returned true.

More than Two Arguments

As mentioned, $and accepts one or more expressions. The previous example uses two expressions. Here’s an example that uses three:

db.data.aggregate(
   [
     { $match: { _id: 1 } },
     { $project: { 
        _id: 0,
        a: 1,
        b: 1,
        c: 1,
        result: { $and: [ 
              { $gt: [ "$a", 9 ] }, 
              { $lt: [ "$b", 3 ] }, 
              { $gt: [ "$c", 30 ] } 
            ] } 
          } 
         }
   ]
)

Result:

{ "a" : 10, "b" : 2, "c" : 20, "result" : false }

In this case the result is false, because the third expression evaluates to false. If one expression evaluates to false, then the result is false ($and needs all expressions to be true before it can return true).

One Argument

Given that $and accepts one or more expressions, it’s possible to provide a single argument.

Example:

db.data.aggregate(
   [
     { $match: { _id: 1 } },
     { $project: { 
        _id: 0,
        a: 1,
        result: { $and: [ { $gt: [ "$a", 9 ] } ] } } 
         }
   ]
)

Result:

{ "a" : 10, "result" : true }

Zero, Null, and Undefined Values

The $and operator evaluates 0, null, and undefined as false.

Suppose we have the following documents:

{ "_id" : 2, "a" : 0, "b" : 2 }
{ "_id" : 3, "a" : 10, "b" : 0 }
{ "_id" : 4, "a" : 0, "b" : 0 }
{ "_id" : 5, "a" : null, "b" : 2 }
{ "_id" : 6, "a" : 10, "b" : null }
{ "_id" : 7, "a" : null, "b" : null }
{ "_id" : 8, "a" : undefined, "b" : 2 }
{ "_id" : 9, "a" : 10, "b" : undefined }
{ "_id" : 10, "a" : undefined, "b" : undefined }

Here’s what happens when we apply $and:

db.data.aggregate(
   [
     { $match: { _id: { $in: [ 2, 3, 4, 5, 6, 7, 8, 9, 10 ] } } },
     { $project: { 
        _id: 0,
        a: 1,
        b: 1,
        result: { $and: [ "$a", "$b" ] } }
         }
   ]
)

Result:

{ "a" : 0, "b" : 2, "result" : false }
{ "a" : 10, "b" : 0, "result" : false }
{ "a" : 0, "b" : 0, "result" : false }
{ "a" : null, "b" : 2, "result" : false }
{ "a" : 10, "b" : null, "result" : false }
{ "a" : null, "b" : null, "result" : false }
{ "a" : undefined, "b" : 2, "result" : false }
{ "a" : 10, "b" : undefined, "result" : false }
{ "a" : undefined, "b" : undefined, "result" : false }

Here, I simply used the field as the expression. As expected, they all returned false.

Here’s what it looks like when we apply just one argument:

db.data.aggregate(
   [
     { $match: { _id: { $in: [ 2, 3, 5, 8 ] } } },
     { $project: { 
        _id: 0,
        a: 1,
        result: { $and: [ "$a" ] } }
         }
   ]
)

Result:

{ "a" : 0, "result" : false }
{ "a" : 10, "result" : true }
{ "a" : null, "result" : false }
{ "a" : undefined, "result" : false }

It returns true when the value is 10 but false in all other instances.

Invoke $and with No Arguments

When invoked with no arguments, the $and operator evaluates to true.

Example:

db.data.aggregate(
   [
     { $match: { _id: { $in: [ 1 ] } } },
     { $project: { 
        _id: 0,
        result: { $and: [ ] } }
         }
   ]
)

Result:

{ "result" : true }