MongoDB: Check if a field is number with $isNumber operator

Updated: February 3, 2024 By: Guest Contributor Post a comment

Introduction to MongoDB’s $isNumber Operator

MongoDB, a popular NoSQL database, provides a dynamic schema that can handle a wide variety of data types. In certain situations, checking the data type of a field becomes important to maintain data integrity and ensure that queries are executed correctly. The $isNumber operator plays a crucial role in these scenarios, allowing developers to verify if a field holds a numeric value. In this tutorial, we will cover the usage of the $isNumber operator with multiple code examples, progressing from basic to more advanced applications.

Prerequisites

  • A running MongoDB instance.
  • Basic understanding of querying in MongoDB.
  • MongoDB shell or a GUI, such as MongoDB Compass, to run the queries.

Understanding the $isNumber Operator

The $isNumber operator is used within MongoDB queries to check if the value of the specified field is a number. This can include integer, double, decimal, long, or any other numeric type recognized by MongoDB. The operator returns a boolean value: true if the field is a number, and false otherwise.

Basic Usage of $isNumber

To begin with, let’s examine how to use the $isNumber operator in its simplest form. Consider the following documents in a collection named products:

{ "_id": 1, "productName": "Laptop", "price": 999 }
{ "_id": 2, "productName": "Smartphone", "price": "799" }
{ "_id": 3, "productName": "Tablet", "price": 449 }

To find only the products where the price is stored as a number, you would use the $isNumber operator as part of the query filter:

db.products.find({ "price": { $isNumber: true } })

The output for the above query would only include the first and third documents, as the price in the second document is not a number:

{ "_id": 1, "productName": "Laptop", "price": 999 }
{ "_id": 3, "productName": "Tablet", "price": 449 }

Combining $isNumber with Other Query Operators

The $isNumber operator can also be combined with other MongoDB query operators for more complex filtering. For example, to find products cheaper than 500 that also have the price stored as a number, you can combine $isNumber with the $lt (less than) operator:

db.products.find({ "price": { $lt: 500, $isNumber: true } })

The above query will return the following document, since it meets both conditions:

{ "_id": 3, "productName": "Tablet", "price": 449 }

Using $isNumber in Aggregation Pipelines

MongoDB’s aggregation framework provides a powerful toolset for transforming and analyzing data. The $isNumber operator can be utilized within an aggregation pipeline to filter or categorize documents. For instance, to count the number of products with numeric prices, you could write:

db.products.aggregate([
  { $match: { "price": { $isNumber: true } } },
  { $count: "numeric_price_count" }
])

This pipeline would produce a result indicating how many products have a price stored as a numeric value:

{ "numeric_price_count": 2 }

Advanced Applications: Conditional Fields with $isNumber

If you want to add a new field to your documents indicating whether the price is numeric, you could use the $addFields stage within an aggregation pipeline combined with the $isNumber operator:

db.products.aggregate([
  { $addFields: { "isPriceNumeric": { $isNumber: "$price" } } }
])

With this aggregation, all documents will now include an isPriceNumeric field indicating true or false based on whether the price field is numeric:

{ "_id": 1, "productName": "Laptop", "price": 999, "isPriceNumeric": true }
{ "_id": 2, "productName": "Smartphone", "price": "799", "isPriceNumeric": false }
{ "_id": 3, "productName": "Tablet", "price": 449, "isPriceNumeric": true }

Type Casting and $isNumber

In MongoDB, when you encounter situations requiring you to work with numeric values stored as strings (or other non-numeric types) and you want to perform operations that depend on these values being treated as numbers, you must explicitly cast them. However, MongoDB does not directly support casting types within a query for the $isNumber check. Instead, you might perform operations that require numeric interpretation of strings in stages, using the aggregation framework for transformations, but keep in mind MongoDB’s aggregation framework does not provide direct type casting for the purpose of $isNumber checks.

Here’s an approach to filter documents based on whether a field can be treated as a numeric value, using a workaround that involves the $regex operator for a pattern that matches numeric strings. This is not a direct cast to numeric types but serves as a way to “select” documents where a field contains numeric-like strings:

db.collection.aggregate([
  {
    $match: {
      // Assuming 'numericStringField' is the field that contains the numeric string
      numericStringField: {
        $regex: /^[+-]?(\d+(\.\d+)?|\.\d+)([eE][+-]?\d+)?$/
      }
    }
  },
  {
    $project: {
      numericStringField: 1,
      // Additional fields as needed
    }
  }
]);

This aggregation pipeline:

  1. Uses $match with a $regex to filter documents where numericStringField looks like a numeric value in string format. The regex pattern matches integer, floating-point, and even scientific notation formatted as strings.
  2. The $project stage is optional and included to illustrate you might then work with these filtered documents, projecting fields as needed.

Note: This method does not truly convert types but filters strings that can be interpreted as numeric. For actual numeric operations on these values (like sorting in numeric order, mathematical operations, etc.), you’d need to handle the conversion in your application code after fetching the data or consider storing the data in the appropriate type if your use case frequently requires numeric operations. MongoDB’s schema design principles recommend storing data in the format most useful for your application to minimize processing overhead.

Conclusion

The $isNumber operator is a versatile tool in MongoDB for ensuring that field values are of numeric type. As illustrated above, it can be used for direct querying or as part of the aggregation framework for more complex analysis and transformations. Understanding and implementing the $isNumber operator can significantly enhance the robustness and reliability of your data management processes within MongoDB.