MongoDB $gte Aggregation Pipeline Operator

In MongoDB, the $gte aggregation pipeline operator compares two values and returns either true or false, depending on whether or not the first value is greater than or equal to the second value.

Example

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

{ "_id" : 1, "a" : 250, "b" : 250 }
{ "_id" : 2, "a" : 300, "b" : 250 }
{ "_id" : 3, "a" : 250, "b" : 300 }

We can use the $gte operator to compare the a and b fields:

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

Result:

{ "a" : 250, "b" : 250, "result" : true }
{ "a" : 300, "b" : 250, "result" : true }
{ "a" : 250, "b" : 300, "result" : false }

In the first document, the a and b fields are equivalent, which results in a return value of true (because a is indeed greater than or equal to b).

In the second document a is greater than b, which results in a return value of true (again because a is indeed greater than or equal to b).

In the third document, a is less than b and therefore the $gte operator returns false (because a is not greater than or equal to b).

Comparing Types

The $gte operator compares both value and type using the specified BSON comparison order for values of different types.

Suppose our collection contains the following documents:

{ "_id" : 4, "a" : 250, "b" : "250" }
{ "_id" : 5, "a" : 250, "b" : NumberDecimal("250") }
{ "_id" : 6, "a" : NumberDecimal("250"), "b" : NumberDecimal("250.00") }
{ "_id" : 7, "a" : "2022-01-03T23:30:15.100Z", "b" : ISODate("2021-01-03T23:30:15.100Z") }

We can apply $gte to the a and b fields of those documents:

db.data.aggregate(
   [
     { $match: { _id: { $in: [ 4, 5, 6, 7 ] } } },
     {
       $project:
          {
            a: 1,
            b: 1,
            result: { $gte: [ "$a", "$b" ] }
          }
     }
   ]
).pretty()

Result:

{ "_id" : 4, "a" : 250, "b" : "250", "result" : false }
{ "_id" : 5, "a" : 250, "b" : NumberDecimal("250"), "result" : true }
{
	"_id" : 6,
	"a" : NumberDecimal("250"),
	"b" : NumberDecimal("250.00"),
	"result" : true
}
{
	"_id" : 7,
	"a" : "2022-01-03T23:30:15.100Z",
	"b" : ISODate("2021-01-03T23:30:15.100Z"),
	"result" : false
}

In document 4, both a and b have a value of 250, but if you look closely at b, it’s a string (it’s surrounded by double quotes). In this case, $gte returns false. If we’d used the $lte operator instead, this would have returned true.

Document 5 also uses a value of 250, but one is a double and the other a decimal. Regardless, these are equivalent, and so $gte returns true.

Similarly, document 6 returns true because both values are equivalent, even though one explicitly uses decimal places and the other doesn’t.

Document 7 returns true because, even though the date/time value in a is greater than the one in b, they use different types to express that date (a uses a date/time string and b uses a Date object). If we’d used the $lte operator instead, this would have returned true due to the BSON comparison order.

Null Values

$gte comparisons can be made against null. And comparing null to null returns true.

Suppose we add the following documents to our collection:

{ "_id" : 8, "a" : 250, "b" : null }
{ "_id" : 9, "a" : null, "b" : 250 }
{ "_id" : 10, "a" : null, "b" : null }

Let’s apply $gte to those documents:

db.data.aggregate(
   [
     { $match: { _id: { $in: [ 8, 9, 10 ] } } },
     {
       $project:
          {
            _id: 0,
            a: 1,
            b: 1,
            result: { $gte: [ "$a", "$b" ] }
          }
     }
   ]
)

Result:

{ "a" : 250, "b" : null, "result" : true }
{ "a" : null, "b" : 250, "result" : false }
{ "a" : null, "b" : null, "result" : true }

Missing Fields

If one of the fields that you’re trying to compare is missing, $gte returns true if the second field is missing, and false if the first is missing.

Suppose we add the following documents to our collection:

{ "_id" : 11, "a" : 250 }
{ "_id" : 12, "b" : 250 }

Let’s apply $gte to those documents:

db.data.aggregate(
   [
     { $match: { _id: { $in: [ 11, 12 ] } } },
     {
       $project:
          {
            _id: 0,
            a: 1,
            b: 1,
            result: { $gte: [ "$a", "$b" ] }
          }
     }
   ]
)

Result:

{ "a" : 250, "result" : true }
{ "b" : 250, "result" : false }

Infinity

Comparing Infinity to Infinity returns true.

Comparing -Infinity to -Infinity returns true.

Comparing Infinity to -Infinity returns true.

Comparing -Infinity to Infinity returns false.

Suppose we add the following documents to our collection:

{ "_id" : 13, "a" : Infinity, "b" : Infinity }
{ "_id" : 14, "a" : -Infinity, "b" : -Infinity }
{ "_id" : 15, "a" : Infinity, "b" : -Infinity }
{ "_id" : 16, "a" : -Infinity, "b" : Infinity }

Let’s apply $gte to those documents:

db.data.aggregate(
   [
     { $match: { _id: { $in: [ 13, 14, 15, 16 ] } } },
     {
       $project:
          {
            _id: 0,
            a: 1,
            b: 1,
            result: { $gte: [ "$a", "$b" ] }
          }
     }
   ]
)

Result:

{ "a" : Infinity, "b" : Infinity, "result" : true }
{ "a" : -Infinity, "b" : -Infinity, "result" : true }
{ "a" : Infinity, "b" : -Infinity, "result" : true }
{ "a" : -Infinity, "b" : Infinity, "result" : false }