MongoDB $type Operator

Beginner
⏱️ 9 min read
📚 Updated: Jul 2026
🎯 5 Examples
Query & Type

What You’ll Learn

The $type operator works with BSON data types. Use it in find() queries to filter documents by field type, or in aggregation pipelines to inspect what type a value actually is.

01

BSON Types

string, number, array.

02

Query Filter

find() and $match.

03

Expression

Return type name.

04

Type Aliases

"number", "string".

05

Use Cases

Schema cleanup, QA.

06

vs $isNumber

Type vs boolean.

Definition and Usage

MongoDB stores values in BSON format, and each value has a type such as string, double, int, array, object, or null. The $type operator lets you work with those types in two ways.

As a query operator, it filters documents where a field matches a specified type. As an aggregation expression, it returns the BSON type name of a value. This is especially useful when cleaning imported data, auditing schema inconsistencies, or debugging mixed-type fields.

💡
Beginner Tip

A field can hold 42 (number) or "42" (string) — they look similar but are different BSON types. $type helps you find and fix those mismatches.

📝 Syntax

Query Syntax (find / $match)

Filter documents where a field is a specific BSON type:

mongosh
{ <field>: { $type: <BSON type> } }

// Examples:
{ age: { $type: "number" } }
{ name: { $type: "string" } }
{ tags: { $type: "array" } }
{ value: { $type: ["string", "null"] } }

Aggregation Expression Syntax

Return the BSON type name of an expression:

mongosh
{ $type: <expression> }

// Examples:
{ $type: "$price" }
{ $type: "$tags" }
{ $type: 42 }

Common BSON Type Aliases

mongosh
// String aliases (most common in tutorials)
"double", "string", "object", "array", "bool", "date",
"null", "int", "long", "decimal", "objectId", "number"

// Numeric codes also work in queries
{ age: { $type: 16 } }   // 16 = int
{ name: { $type: 2 } }   // 2  = string

Syntax Rules

  • Query form — use on a field in find() or $match filters.
  • Expression form — use inside $project, $addFields, $cond, or $expr.
  • "number" — matches int, long, double, and decimal types.
  • Array of types — query form only; matches any listed type.
  • Expression form returns a string like "double" or "string".
  • Missing fields in expression form return "missing".

💡 Query Operator vs Aggregation Expression

Query{ price: { $type: "number" } } (filters documents)
Expression{ priceType: { $type: "$price" } } (returns type name)
$expr filter{ $expr: { $eq: [ { $type: "$price" }, "string" ] } }
See $isNumber for a boolean numeric check in expressions

⚡ Quick Reference

QuestionAnswer
Operator typeQuery operator and aggregation expression
Query syntax{ field: { $type: "string" } }
Expression syntax{ $type: "$field" }
Expression outputBSON type name string (e.g. "double", "array")
Multiple types{ $type: ["string", "null"] } in queries
Common stagesfind(), $match, $project, $addFields
Query: string
{
  name: {
    $type: "string"
  }
}

Filter string fields

Query: number
{
  score: {
    $type: "number"
  }
}

Any numeric type

Expression
{
  $type: "$value"
}

Returns type name

Multiple types
{
  value: {
    $type: ["string", "null"]
  }
}

String or null

Examples Gallery

Filter a mixed-type records collection by BSON type in queries, inspect types in aggregation, and find schema inconsistencies with $type.

📚 Query by BSON Type

Use $type in find() to filter documents where a field has a specific type.

Sample Input Documents

A records collection with mixed types in the value field:

mongosh
[
  { "_id": 1, "label": "Score A", "value": 95 },
  { "_id": 2, "label": "Score B", "value": "88" },
  { "_id": 3, "label": "Tags",    "value": ["mongo", "db"] },
  { "_id": 4, "label": "Empty",   "value": null },
  { "_id": 5, "label": "Meta",    "value": { active: true } }
]

Example 1 — Find Documents Where value Is a String

Query filter using the string type alias:

mongosh
db.records.find({
  value: { $type: "string" }
})

// Returns: { _id: 2, label: "Score B", value: "88" }

How It Works

The numeric 95 is excluded because its BSON type is int or double, not string. Only the quoted "88" matches.

📈 More Query Patterns

Filter by numeric types, null values, and multiple allowed types.

Example 2 — Find Documents Where value Is a Number

Use the "number" alias to match any numeric BSON type:

mongosh
db.records.find({
  value: { $type: "number" }
})

// Returns: { _id: 1, label: "Score A", value: 95 }

How It Works

"number" matches int, long, double, and decimal. The string "88" does not match even though it looks numeric.

Example 3 — Find null Values or Match Multiple Types

Find explicit nulls, or allow string or null:

mongosh
// Documents where value is null
db.records.find({
  value: { $type: "null" }
})

// Documents where value is string OR null
db.records.find({
  value: { $type: ["string", "null"] }
})

// Returns for array query:
// { _id: 2, label: "Score B", value: "88" }
// { _id: 4, label: "Empty",   value: null }

How It Works

Passing an array of types matches documents where the field is any of those types. Useful for flexible schema validation during data cleanup.

🔍 Inspect Types in Aggregation

Use $type as an expression to audit field types across your collection.

Example 4 — Project the BSON Type of Each Field

Add a type label for every document’s value field:

mongosh
db.records.aggregate([
  {
    $project: {
      label: 1,
      value: 1,
      valueType: { $type: "$value" }
    }
  }
])

How It Works

Expression form $type returns the exact BSON type name. This is ideal for data quality reports that flag unexpected types.

Example 5 — Filter with $expr and $type Expression

Combine expression $type with $match to filter in a pipeline:

mongosh
db.records.aggregate([
  {
    $match: {
      $expr: {
        $eq: [
          { $type: "$value" },
          "string"
        ]
      }
    }
  },
  {
    $project: {
      label: 1,
      value: 1,
      valueType: { $type: "$value" }
    }
  }
])

// Same result as find({ value: { $type: "string" } })
// but useful when type logic is part of a longer pipeline

How It Works

$expr lets you use aggregation expressions inside $match. Compare the returned type string with $eq for flexible filtering.

Bonus — Flag Schema Issues with $cond

Mark records where value is not a number when it should be:

mongosh
db.records.aggregate([
  {
    $project: {
      label: 1,
      value: 1,
      valueType: { $type: "$value" },
      needsFix: {
        $cond: [
          {
            $in: [
              { $type: "$value" },
              ["int", "long", "double", "decimal"]
            ]
          },
          false,
          true
        ]
      }
    }
  }
])

// Score B (value: "88") → needsFix: true
// Score A (value: 95)   → needsFix: false

How It Works

Pair $type with $in and $cond to build data-quality flags directly in your pipeline.

🚀 Use Cases

  • Schema auditing — find fields stored as the wrong BSON type after imports.
  • Data cleanup — filter string numbers like "42" before converting them.
  • Null detection — locate explicit null values vs missing fields.
  • Pipeline validation — inspect types before applying math or array operators.
  • Migration checks — verify documents match expected types after schema changes.

🧠 How $type Works

1

MongoDB reads the field or expression

In queries, a field path is checked. In expressions, the input expression is evaluated first.

Input
2

BSON type is determined

MongoDB identifies the stored type: string, int, array, object, null, and so on.

Type
3

Filter or return the result

Query form keeps matching documents. Expression form returns the type name string.

Output
=

Type-aware data

Find mismatches, filter by type, and build safer aggregation pipelines.

Conclusion

The $type operator is a versatile tool for working with BSON types in MongoDB. Use it in queries to filter documents by field type, and in aggregation expressions to inspect what type a value actually is.

Remember the two forms: query filter { field: { $type: "string" } } vs expression { $type: "$field" }. For boolean numeric checks, see $isNumber and $isArray. Next in the series: $week.

💡 Best Practices

✅ Do

  • Use query $type for simple type filters in find()
  • Use expression $type to audit schema inconsistencies
  • Prefer "number" when any numeric subtype is acceptable
  • Pass type arrays when multiple types are valid
  • Combine with $expr for type logic inside pipelines

❌ Don’t

  • Confuse query and expression syntax — they behave differently
  • Assume "42" matches { $type: "number" }
  • Use expression $type as a direct query filter without $expr
  • Forget that missing fields return "missing" in expressions
  • Replace $isNumber with $type when you only need true/false

Key Takeaways

Knowledge Unlocked

Five things to remember about $type

Use these points when filtering or inspecting BSON types.

5
Core concepts
📝 02

Two Forms

Query vs expr.

Syntax
🔢 03

"number"

All numeric types.

Alias
🛠 04

Type Arrays

Multiple matches.

Pattern
05

vs $isNumber

Name vs boolean.

Compare

❓ Frequently Asked Questions

$type checks BSON data types. In find() queries it filters documents where a field matches a given type. In aggregation expressions it returns the BSON type name of a value (e.g. "string", "double", "array").
Yes. As a query operator, use { field: { $type: "string" } } in find() or $match. As an aggregation expression, use { $type: "$field" } inside $project, $addFields, or $cond to return the type name.
The alias "number" matches any numeric BSON type: int, long, double, and decimal. It is useful when you want all numbers regardless of specific numeric subtype.
Yes. In queries you can pass an array: { value: { $type: ["string", "null"] } } returns documents where value is a string or null.
$type returns the BSON type name (or filters by type in queries) and works for any type. $isNumber returns true or false for numeric types only inside aggregation expressions.

Continue the Operator Series

Move on to $week for date extraction, or review $isNumber for boolean type checks.

Next: $week →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

5 people found this page helpful