DocsHub
Querying

Element Operators

Learn how to query documents based on whether a field exists or what type it is using $exists and $type.

Element Operators

So far, every operator we used filters documents based on the value of a field. Element operators are different — they filter documents based on the field itself.

  • $exists — does this field exist in the document?
  • $type — what data type is this field?

These are especially useful in MongoDB because documents in the same collection can have different fields and different types.


$exists

$exists matches documents where a field either exists or does not exist. Pass true to find documents that have the field, and false to find documents that do not.

Syntax

db.collection.find({ field: { $exists: true } })
db.collection.find({ field: { $exists: false } })

Example — Find students who have a phone number

Not every student document has a phone field. $exists lets you find only the ones that do:

db.students.find({ phone: { $exists: true } })

Example — Find students who do NOT have a phone number

db.students.find({ phone: { $exists: false } })

Example — Find students who have a graduationDate set

db.students.find({ graduationDate: { $exists: true } })

$exists with null

There is an important difference between a field not existing and a field being null:

// Document A — field does not exist
{ name: "Ali Hassan", age: 16 }

// Document B — field exists but is null
{ name: "Sara Ahmed", age: 15, graduationDate: null }
// $exists: true matches Document B but NOT Document A
db.students.find({ graduationDate: { $exists: true } })

// $exists: false matches Document A but NOT Document B
db.students.find({ graduationDate: { $exists: false } })

$exists: true matches any document where the field is present — even if its value is null.

In a real school system, you will often have fields that only some documents have — like transferredFrom, graduationDate, or scholarshipAmount. Use $exists to find documents that have or are missing these optional fields.


Combining $exists with Other Operators

You can combine $exists with other operators to be more precise:

// Students who have a phone number AND are enrolled
db.students.find({
  phone: { $exists: true },
  enrolled: true
})

// Students who are missing an address field
db.students.find({
  address: { $exists: false }
})

$type

$type matches documents where a field is a specific BSON data type. This is useful when your collection has inconsistent data — for example, some documents store age as a number and others accidentally stored it as a string.

Syntax

You can pass either the BSON type name as a string or its numeric code:

db.collection.find({ field: { $type: "string" } })
db.collection.find({ field: { $type: 2 } })  // 2 is the code for string

Using the string name is cleaner and easier to read.

Common BSON type names

TypeString aliasNumber code
Double"double"1
String"string"2
Object"object"3
Array"array"4
Boolean"bool"8
Date"date"9
Null"null"10
Integer (32-bit)"int"16
Integer (64-bit)"long"18
ObjectId"objectId"7

Example — Find students where age is stored as a string

Someone accidentally inserted age as a string instead of a number. Find those documents:

db.students.find({ age: { $type: "string" } })

Now you know which documents need fixing.

Example — Find students where age is stored as a number

db.students.find({ age: { $type: "double" } })

Example — Find students where subjects is actually an array

db.students.find({ subjects: { $type: "array" } })

Example — Find documents where enrollmentDate is a real Date type

db.students.find({ enrollmentDate: { $type: "date" } })

This is useful to catch documents where someone stored the date as a string instead of a proper Date object.


$type with Multiple Types

You can pass an array of types to match documents where a field is any one of those types:

// Find students where age is stored as either int or double
db.students.find({
  age: { $type: ["int", "double"] }
})

Practical Use — Cleaning Inconsistent Data

The most common real-world use of $type is finding and fixing data quality issues. In our school system, imagine someone inserted some students with age as a string:

// Step 1 — find the bad documents
db.students.find({ age: { $type: "string" } })
// Step 2 — you now know which ones to fix
// Fix them one by one or write a script to convert them

If your collection has mixed types in the same field — some documents storing age as a number and others as a string — comparison operators like $gt and $lt will not work correctly on the string documents. Always make sure fields have consistent types across all documents.


Combining $exists and $type

You can use both together for precise field checks:

// Students who have a graduationDate AND it is a proper Date type
db.students.find({
  graduationDate: {
    $exists: true,
    $type: "date"
  }
})

// Students who have an age field AND it is stored as a number
db.students.find({
  age: {
    $exists: true,
    $type: "double"
  }
})

School System Examples

// Find students who have a guardian field set
db.students.find({ guardian: { $exists: true } })

// Find students missing an address
db.students.find({ address: { $exists: false } })

// Find teachers who have a contactNumber field
db.teachers.find({ contactNumber: { $exists: true } })

// Find any student where age was accidentally stored as a string
db.students.find({ age: { $type: "string" } })

// Find students where subjects is an array
db.students.find({ subjects: { $type: "array" } })

// Find students who have a graduationDate that is a real Date
db.students.find({
  graduationDate: {
    $exists: true,
    $type: "date"
  }
})

// Find documents where address is an embedded object
db.students.find({ address: { $type: "object" } })

Quick Reference

OperatorWhat it doesExample
$exists: trueField exists in the document{ phone: { $exists: true } }
$exists: falseField does not exist{ phone: { $exists: false } }
$type: "string"Field is a string{ age: { $type: "string" } }
$type: "double"Field is a number{ age: { $type: "double" } }
$type: "date"Field is a Date{ dob: { $type: "date" } }
$type: "array"Field is an array{ subjects: { $type: "array" } }

Use $exists and $type during data audits — before you add validation rules, run these queries to check how consistent your existing data is. You will often find surprising things — missing fields, wrong types, null values where you expected real data.

On this page