$isNumber (aggregation)
On this page
Definition
$isNumber
New in version 4.4.
$isNumber
checks if the specified expression resolves to one of the following numeric BSON types:$isNumber
returns:true
if the expression resolves to a number.false
if the expression resolves to any other BSON type,null
, or a missing field.
$isNumber
has the following operator expression syntax:{ $isNumber: <expression> } The argument can be any valid expression.
Tip
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 ofreading
is 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" : "M044", "class_desc" : "Introduction to MongoDB 4.4", "grade" : "A" }, { "student_id" : 457864153, "class_id" : "M103", "class_desc" : "Basic Cluster Administration", "grade" : 3.0 }, { "student_id" : 978451637, "class_id" : "M320", "class_desc" : "MongoDB Data Modeling", "grade" : "C" }, { "student_id" : 978451637, "class_id" : "M001", "class_desc" : "MongoDB Basics", "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
,grades
already contains the numeric point value. Setpoints
equal togrades
.If
false
,grades
contains a string letter value. Use$switch
to 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 }