MongoDB $isNumber

From MongoDB 4.4, you can use the $isNumber aggregation pipeline operator to check whether or not a value is a number.

It accepts any valid expression, and returns true if the expression is a number, false if it’s not.

Specifically, $isNumber checks whether the expression resolves to one of the following BSON types:

  • Integer
  • Decimal
  • Double
  • Long

It returns true if it does.

It returns false if the expression resolves to any other BSON type, null, or a missing field.

Example

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

{ "_id" : 1, "name" : "Fetch", "weight" : 30 } 

We can use the following code to see which fields are numeric:

db.dogs.aggregate(
  [
    {
      $project:
        { 
          _id: { $isNumber: "$_id" },
          name: { $isNumber: "$name" },
          weight: { $isNumber: "$weight" }
        }
    }
  ]
)

Result:

{ "_id" : true, "name" : false, "weight" : true }

We can see that the _id and weight fields are numeric, but the name field is not (it’s a string).

Example 2

Here’s another example that contains various fields of differing BSON types.

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

{
	"_id" : ObjectId("601738d7c8eb4369cf6ad9de"),
	"double" : 123.75,
	"string" : "123",
	"boolean" : true,
	"date" : ISODate("2020-12-31T23:30:15.123Z"),
	"integer" : 123,
	"long" : NumberLong(123),
	"decimal" : NumberDecimal("123.75"),
	"object" : {
		"a" : 1
	},
	"array" : [
		1,
		2,
		3
	]
}

For the purpose of this article, I’ve named each field to reflect its BSON type.

We can now use the following code to return either true or false for each field, depending on whether or not the field is a number:

db.types.aggregate(
  [
    {
      $project:
        { 
          _id: { $isNumber: "$_id" },
          double: { $isNumber: "$double" },
          string: { $isNumber: "$string" },
          boolean: { $isNumber: "$boolean" },
          date: { $isNumber: "$date" },
          integer: { $isNumber: "$integer" },
          long: { $isNumber: "$long" },
          decimal: { $isNumber: "$decimal" },
          object: { $isNumber: "$object" },
          array: { $isNumber: "$array" }
        }
    }
  ]
).pretty()

Result:

{
	"_id" : false,
	"double" : true,
	"string" : false,
	"boolean" : false,
	"date" : false,
	"integer" : true,
	"long" : true,
	"decimal" : true,
	"object" : false,
	"array" : false
}