$isNumber (aggregation)
Definition
$isNumber$isNumberchecks if the specified expression resolves to one of the following numeric BSON types:$isNumberreturns:trueif the expression resolves to a number.falseif the expression resolves to any other BSON type,null, or a missing field.
$isNumberhas the following operator expression syntax:{ $isNumber: <expression> } The argument can be any valid expression.
See also:
$type (Aggregation)- returns the BSON type of the argument.$type (Query)- filters fields based on BSON type.
Example
Use $isNumber to Check if a Field is Numeric
Issue the following operation against the examples.sensors
collection to populate test data:
db.getSiblingDB("examples").sensors.insertMany([   { "_id" : 1, "reading" : NumberDecimal(26.0) },   { "_id" : 2, "reading" : NumberLong(25.0) },   { "_id" : 3, "reading" : NumberInt(24) },   { "_id" : 4, "reading" : 24.0 },   { "_id" : 5, "reading" : "24" },   { "_id" : 6, "reading" : [ NumberDecimal(26) ]} ]) 
The following aggregation uses the $addFields aggregation
stage to add the following fields to each document:
isNumber- Indicates whether the value ofreadingis an integer, decimal, double, or long.type- Indicates the BSON type ofreading.
db.sensors.aggregate([{   $addFields : {     "isNumber" : { $isNumber : "$reading" },     "hasType" : {$type : "$reading"}   } }]) 
The aggregation operation returns the following results:
{ "_id" : 1, "reading" : NumberDecimal("26.0000000000000"), "isNum " : true, "type" : "decimal" } { "_id" : 2, "reading" : NumberLong(25), "isNum " : true, "type" : "long" } { "_id" : 3, "reading" : 24, "isNum " : true, "type" : "int" } { "_id" : 4, "reading" : 24, "isNum " : true, "type" : "double" } { "_id" : 5, "reading" : "24", "isNum " : false, "type" : "string" } { "_id" : 6, "reading" : [ NumberDecimal("26.0000000000000") ], "isNum " : false, "type" : "array" } 
Conditionally Modify Fields using $isNumber
The grades collection contains data on student grades. The grade
field may either store a string letter grade or a numeric point value.
db.getSiblingDB("examples").grades.insertMany([   {     "student_id" : 457864153,     "class_id" : "01",     "class_desc" : "Algebra",     "grade" : "A"   },   {     "student_id" : 457864153,     "class_id" : "02",     "class_desc" : "Chemistry",     "grade" : 3.0   },   {     "student_id" : 978451637,     "class_id" : "03",     "class_desc" : "Physics",     "grade" : "C"   },   {     "student_id" : 978451637,     "class_id" : "04",     "class_desc" : "English",     "grade" : 4.0   } ]) 
The following aggregation uses the $addFields stage to add a
points field containing the numeric grade value for that course. The
stage uses the $cond operator to set the value of
points based on the output of $isNumber:
If
true,gradesalready contains the numeric point value. Setpointsequal togrades.If
false,gradescontains a string letter value. Use$switchto convert the letter grade to its equivalent point value and assign topoints.
The aggregation pipeline then uses the $group stage to
group on the student_id and calculate the student's
average GPA.
 db.getSiblingDB("examples").grades.aggregate([    {      $addFields: {        "points" : {          $cond : {            if : { $isNumber : "$grade" },            then: "$grade" ,            else: {              $switch : {                branches: [                  { case: {$eq : ["$grade" , "A"]}, then : 4.0 },                  { case: {$eq : ["$grade" , "B"]}, then : 3.0 },                  { case: {$eq : ["$grade" , "C"]}, then : 2.0 },                  { case: {$eq : ["$grade" , "D"]}, then : 1.0 },                  { case: {$eq : ["$grade" , "F"]}, then : 0.0 }                ]              }            }          }        }      }    },    {      $group : {        _id : "$student_id",        GPA : {          $avg : "$points"        }      }    } ]) 
The aggregation pipeline outputs one document per unique student_id
with that student's GPA grade point average:
{ "_id" : 457864153, "GPA" : 3.5 } { "_id" : 978451637, "GPA" : 3 }